@algorandfoundation/algokit-utils 9.2.0 → 9.2.1-beta.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.
- package/_virtual/_rolldown/runtime.js +33 -0
- package/_virtual/_rolldown/runtime.mjs +13 -0
- package/account/account.d.ts +25 -30
- package/account/account.js +151 -146
- package/account/account.js.map +1 -1
- package/account/account.mjs +149 -144
- package/account/account.mjs.map +1 -1
- package/account/get-account-config-from-environment.d.ts +7 -2
- package/account/get-account-config-from-environment.js +19 -21
- package/account/get-account-config-from-environment.js.map +1 -1
- package/account/get-account-config-from-environment.mjs +19 -19
- package/account/get-account-config-from-environment.mjs.map +1 -1
- package/account/get-account.d.ts +14 -12
- package/account/get-account.js +56 -59
- package/account/get-account.js.map +1 -1
- package/account/get-account.mjs +56 -57
- package/account/get-account.mjs.map +1 -1
- package/account/get-dispenser-account.d.ts +9 -5
- package/account/get-dispenser-account.js +20 -18
- package/account/get-dispenser-account.js.map +1 -1
- package/account/get-dispenser-account.mjs +20 -16
- package/account/get-dispenser-account.mjs.map +1 -1
- package/account/mnemonic-account.d.ts +7 -3
- package/account/mnemonic-account.js +17 -17
- package/account/mnemonic-account.js.map +1 -1
- package/account/mnemonic-account.mjs +15 -15
- package/account/mnemonic-account.mjs.map +1 -1
- package/amount.d.ts +40 -35
- package/amount.js +33 -34
- package/amount.js.map +1 -1
- package/amount.mjs +33 -32
- package/amount.mjs.map +1 -1
- package/app-client.d.ts +10 -6
- package/app-client.js +91 -86
- package/app-client.js.map +1 -1
- package/app-client.mjs +91 -84
- package/app-client.mjs.map +1 -1
- package/app-deploy.d.ts +26 -24
- package/app-deploy.js +235 -253
- package/app-deploy.js.map +1 -1
- package/app-deploy.mjs +233 -251
- package/app-deploy.mjs.map +1 -1
- package/app.d.ts +45 -46
- package/app.js +253 -271
- package/app.js.map +1 -1
- package/app.mjs +249 -267
- package/app.mjs.map +1 -1
- package/asset.d.ts +16 -12
- package/asset.js +116 -122
- package/asset.js.map +1 -1
- package/asset.mjs +116 -120
- package/asset.mjs.map +1 -1
- package/config.d.ts +7 -2
- package/config.js +5 -7
- package/config.js.map +1 -1
- package/config.mjs +5 -4
- package/config.mjs.map +1 -1
- package/debugging/debugging.d.ts +5 -1
- package/debugging/debugging.js +11 -11
- package/debugging/debugging.js.map +1 -1
- package/debugging/debugging.mjs +11 -9
- package/debugging/debugging.mjs.map +1 -1
- package/dispenser-client.d.ts +7 -2
- package/dispenser-client.js +23 -24
- package/dispenser-client.js.map +1 -1
- package/dispenser-client.mjs +23 -22
- package/dispenser-client.mjs.map +1 -1
- package/index.d.ts +27 -18
- package/index.js +140 -143
- package/index.mjs +27 -29
- package/indexer-lookup.d.ts +18 -11
- package/indexer-lookup.js +112 -120
- package/indexer-lookup.js.map +1 -1
- package/indexer-lookup.mjs +105 -118
- package/indexer-lookup.mjs.map +1 -1
- package/localnet/get-kmd-wallet-account.d.ts +9 -7
- package/localnet/get-kmd-wallet-account.js +28 -26
- package/localnet/get-kmd-wallet-account.js.map +1 -1
- package/localnet/get-kmd-wallet-account.mjs +28 -24
- package/localnet/get-kmd-wallet-account.mjs.map +1 -1
- package/localnet/get-localnet-dispenser-account.d.ts +7 -5
- package/localnet/get-localnet-dispenser-account.js +17 -15
- package/localnet/get-localnet-dispenser-account.js.map +1 -1
- package/localnet/get-localnet-dispenser-account.mjs +17 -13
- package/localnet/get-localnet-dispenser-account.mjs.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.d.ts +10 -8
- package/localnet/get-or-create-kmd-wallet-account.js +28 -26
- package/localnet/get-or-create-kmd-wallet-account.js.map +1 -1
- package/localnet/get-or-create-kmd-wallet-account.mjs +28 -24
- package/localnet/get-or-create-kmd-wallet-account.mjs.map +1 -1
- package/localnet/is-localnet.d.ts +7 -3
- package/localnet/is-localnet.js +9 -10
- package/localnet/is-localnet.js.map +1 -1
- package/localnet/is-localnet.mjs +9 -8
- package/localnet/is-localnet.mjs.map +1 -1
- package/network-client.d.ts +17 -15
- package/network-client.js +115 -116
- package/network-client.js.map +1 -1
- package/network-client.mjs +115 -114
- package/network-client.mjs.map +1 -1
- package/package.json +12 -3
- package/testing/account.d.ts +11 -9
- package/testing/account.js +31 -33
- package/testing/account.js.map +1 -1
- package/testing/account.mjs +29 -31
- package/testing/account.mjs.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.d.ts +7 -2
- package/testing/fixtures/algokit-log-capture-fixture.js +36 -41
- package/testing/fixtures/algokit-log-capture-fixture.js.map +1 -1
- package/testing/fixtures/algokit-log-capture-fixture.mjs +36 -39
- package/testing/fixtures/algokit-log-capture-fixture.mjs.map +1 -1
- package/testing/fixtures/algorand-fixture.d.ts +9 -4
- package/testing/fixtures/algorand-fixture.js +67 -62
- package/testing/fixtures/algorand-fixture.js.map +1 -1
- package/testing/fixtures/algorand-fixture.mjs +66 -59
- package/testing/fixtures/algorand-fixture.mjs.map +1 -1
- package/testing/index.d.ts +7 -5
- package/testing/index.js +13 -18
- package/testing/index.mjs +7 -7
- package/testing/indexer.d.ts +5 -1
- package/testing/indexer.js +28 -37
- package/testing/indexer.js.map +1 -1
- package/testing/indexer.mjs +28 -35
- package/testing/indexer.mjs.map +1 -1
- package/testing/test-logger.d.ts +41 -36
- package/testing/test-logger.js +71 -76
- package/testing/test-logger.js.map +1 -1
- package/testing/test-logger.mjs +71 -74
- package/testing/test-logger.mjs.map +1 -1
- package/testing/transaction-logger.d.ts +30 -27
- package/testing/transaction-logger.js +77 -93
- package/testing/transaction-logger.js.map +1 -1
- package/testing/transaction-logger.mjs +74 -90
- package/testing/transaction-logger.mjs.map +1 -1
- package/transaction/legacy-bridge.js +100 -111
- package/transaction/legacy-bridge.js.map +1 -1
- package/transaction/legacy-bridge.mjs +97 -108
- package/transaction/legacy-bridge.mjs.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.d.ts +7 -5
- package/transaction/perform-atomic-transaction-composer-simulate.js +31 -36
- package/transaction/perform-atomic-transaction-composer-simulate.js.map +1 -1
- package/transaction/perform-atomic-transaction-composer-simulate.mjs +28 -33
- package/transaction/perform-atomic-transaction-composer-simulate.mjs.map +1 -1
- package/transaction/transaction.d.ts +34 -35
- package/transaction/transaction.js +716 -914
- package/transaction/transaction.js.map +1 -1
- package/transaction/transaction.mjs +713 -911
- package/transaction/transaction.mjs.map +1 -1
- package/transfer/transfer-algos.d.ts +9 -5
- package/transfer/transfer-algos.js +26 -27
- package/transfer/transfer-algos.js.map +1 -1
- package/transfer/transfer-algos.mjs +26 -25
- package/transfer/transfer-algos.mjs.map +1 -1
- package/transfer/transfer.d.ts +11 -8
- package/transfer/transfer.js +94 -100
- package/transfer/transfer.js.map +1 -1
- package/transfer/transfer.mjs +94 -98
- package/transfer/transfer.mjs.map +1 -1
- package/types/account-manager.d.ts +432 -429
- package/types/account-manager.js +591 -602
- package/types/account-manager.js.map +1 -1
- package/types/account-manager.mjs +587 -599
- package/types/account-manager.mjs.map +1 -1
- package/types/account.d.ts +192 -202
- package/types/account.js +91 -88
- package/types/account.js.map +1 -1
- package/types/account.mjs +88 -86
- package/types/account.mjs.map +1 -1
- package/types/algo-http-client-with-retry.d.ts +15 -10
- package/types/algo-http-client-with-retry.js +70 -92
- package/types/algo-http-client-with-retry.js.map +1 -1
- package/types/algo-http-client-with-retry.mjs +69 -90
- package/types/algo-http-client-with-retry.mjs.map +1 -1
- package/types/algorand-client-transaction-creator.d.ts +778 -771
- package/types/algorand-client-transaction-creator.js +733 -732
- package/types/algorand-client-transaction-creator.js.map +1 -1
- package/types/algorand-client-transaction-creator.mjs +732 -730
- package/types/algorand-client-transaction-creator.mjs.map +1 -1
- package/types/algorand-client-transaction-sender.d.ts +1090 -1360
- package/types/algorand-client-transaction-sender.js +930 -961
- package/types/algorand-client-transaction-sender.js.map +1 -1
- package/types/algorand-client-transaction-sender.mjs +927 -959
- package/types/algorand-client-transaction-sender.mjs.map +1 -1
- package/types/algorand-client.d.ts +239 -236
- package/types/algorand-client.js +322 -320
- package/types/algorand-client.js.map +1 -1
- package/types/algorand-client.mjs +321 -318
- package/types/algorand-client.mjs.map +1 -1
- package/types/amount.d.ts +47 -43
- package/types/amount.js +66 -70
- package/types/amount.js.map +1 -1
- package/types/amount.mjs +63 -68
- package/types/amount.mjs.map +1 -1
- package/types/app-arc56.d.ts +235 -272
- package/types/app-arc56.js +124 -170
- package/types/app-arc56.js.map +1 -1
- package/types/app-arc56.mjs +121 -168
- package/types/app-arc56.mjs.map +1 -1
- package/types/app-client.d.ts +1128 -2009
- package/types/app-client.js +1633 -1791
- package/types/app-client.js.map +1 -1
- package/types/app-client.mjs +1624 -1783
- package/types/app-client.mjs.map +1 -1
- package/types/app-deployer.d.ts +139 -141
- package/types/app-deployer.js +344 -384
- package/types/app-deployer.js.map +1 -1
- package/types/app-deployer.mjs +341 -382
- package/types/app-deployer.mjs.map +1 -1
- package/types/app-factory.d.ts +762 -932
- package/types/app-factory.js +496 -488
- package/types/app-factory.js.map +1 -1
- package/types/app-factory.mjs +491 -484
- package/types/app-factory.mjs.map +1 -1
- package/types/app-manager.d.ts +304 -310
- package/types/app-manager.js +422 -475
- package/types/app-manager.js.map +1 -1
- package/types/app-manager.mjs +419 -473
- package/types/app-manager.mjs.map +1 -1
- package/types/app-spec.d.ts +118 -117
- package/types/app-spec.js +125 -135
- package/types/app-spec.js.map +1 -1
- package/types/app-spec.mjs +121 -132
- package/types/app-spec.mjs.map +1 -1
- package/types/app.d.ts +229 -241
- package/types/app.js +36 -28
- package/types/app.js.map +1 -1
- package/types/app.mjs +33 -26
- package/types/app.mjs.map +1 -1
- package/types/asset-manager.d.ts +204 -199
- package/types/asset-manager.js +165 -174
- package/types/asset-manager.js.map +1 -1
- package/types/asset-manager.mjs +164 -172
- package/types/asset-manager.mjs.map +1 -1
- package/types/asset.d.ts +95 -91
- package/types/asset.js +0 -3
- package/types/asset.mjs +0 -2
- package/types/async-event-emitter.d.ts +18 -13
- package/types/async-event-emitter.js +37 -49
- package/types/async-event-emitter.js.map +1 -1
- package/types/async-event-emitter.mjs +36 -47
- package/types/async-event-emitter.mjs.map +1 -1
- package/types/client-manager.d.ts +453 -451
- package/types/client-manager.js +602 -598
- package/types/client-manager.js.map +1 -1
- package/types/client-manager.mjs +597 -594
- package/types/client-manager.mjs.map +1 -1
- package/types/composer.d.ts +1211 -1258
- package/types/composer.js +1436 -1498
- package/types/composer.js.map +1 -1
- package/types/composer.mjs +1430 -1493
- package/types/composer.mjs.map +1 -1
- package/types/config.d.ts +53 -48
- package/types/config.js +78 -77
- package/types/config.js.map +1 -1
- package/types/config.mjs +77 -75
- package/types/config.mjs.map +1 -1
- package/types/debugging.d.ts +25 -23
- package/types/debugging.js +9 -11
- package/types/debugging.js.map +1 -1
- package/types/debugging.mjs +8 -9
- package/types/debugging.mjs.map +1 -1
- package/types/dispenser-client.d.ts +57 -52
- package/types/dispenser-client.js +120 -141
- package/types/dispenser-client.js.map +1 -1
- package/types/dispenser-client.mjs +119 -139
- package/types/dispenser-client.mjs.map +1 -1
- package/types/expand.d.ts +5 -3
- package/types/expand.js +0 -3
- package/types/expand.mjs +0 -2
- package/types/indexer.d.ts +104 -100
- package/types/indexer.js +36 -31
- package/types/indexer.js.map +1 -1
- package/types/indexer.mjs +32 -30
- package/types/indexer.mjs.map +1 -1
- package/types/instance-of.d.ts +5 -3
- package/types/instance-of.js +0 -3
- package/types/instance-of.mjs +0 -2
- package/types/kmd-account-manager.d.ts +75 -70
- package/types/kmd-account-manager.js +150 -184
- package/types/kmd-account-manager.js.map +1 -1
- package/types/kmd-account-manager.mjs +147 -182
- package/types/kmd-account-manager.mjs.map +1 -1
- package/types/lifecycle-events.d.ts +13 -8
- package/types/lifecycle-events.js +10 -7
- package/types/lifecycle-events.js.map +1 -1
- package/types/lifecycle-events.mjs +9 -7
- package/types/lifecycle-events.mjs.map +1 -1
- package/types/logging.d.ts +15 -11
- package/types/logging.js +30 -31
- package/types/logging.js.map +1 -1
- package/types/logging.mjs +29 -29
- package/types/logging.mjs.map +1 -1
- package/types/logic-error.d.ts +33 -29
- package/types/logic-error.js +50 -49
- package/types/logic-error.js.map +1 -1
- package/types/logic-error.mjs +49 -47
- package/types/logic-error.mjs.map +1 -1
- package/types/network-client.d.ts +32 -27
- package/types/network-client.js +10 -9
- package/types/network-client.js.map +1 -1
- package/types/network-client.mjs +9 -7
- package/types/network-client.mjs.map +1 -1
- package/types/testing.d.ts +131 -132
- package/types/testing.js +0 -3
- package/types/testing.mjs +0 -2
- package/types/transaction.d.ts +110 -110
- package/types/transaction.js +0 -3
- package/types/transaction.mjs +0 -2
- package/types/transfer.d.ts +70 -66
- package/types/transfer.js +0 -3
- package/types/transfer.mjs +0 -2
- package/util.js +73 -118
- package/util.js.map +1 -1
- package/util.mjs +73 -116
- package/util.mjs.map +1 -1
- package/account/index.d.ts +0 -5
- package/debugging/index.d.ts +0 -1
- package/index.js.map +0 -1
- package/index.mjs.map +0 -1
- package/localnet/index.d.ts +0 -4
- package/testing/_asset.d.ts +0 -3
- package/testing/fixtures/index.d.ts +0 -2
- package/testing/index.js.map +0 -1
- package/testing/index.mjs.map +0 -1
- package/transaction/index.d.ts +0 -2
- package/transaction/legacy-bridge.d.ts +0 -35
- package/transfer/index.d.ts +0 -2
- package/types/asset.js.map +0 -1
- package/types/asset.mjs.map +0 -1
- package/types/expand.js.map +0 -1
- package/types/expand.mjs.map +0 -1
- package/types/instance-of.js.map +0 -1
- package/types/instance-of.mjs.map +0 -1
- package/types/testing.js.map +0 -1
- package/types/testing.mjs.map +0 -1
- package/types/transaction.js.map +0 -1
- package/types/transaction.mjs.map +0 -1
- package/types/transfer.js.map +0 -1
- package/types/transfer.mjs.map +0 -1
- package/util.d.ts +0 -48
|
@@ -1,94 +1,72 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_config = require("../config.js");
|
|
3
|
+
let algosdk = require("algosdk");
|
|
4
|
+
let algosdk_client = require("algosdk/client");
|
|
5
|
+
//#region src/types/algo-http-client-with-retry.ts
|
|
7
6
|
/** A HTTP Client that wraps the Algorand SDK HTTP Client with retries */
|
|
8
|
-
class AlgoHttpClientWithRetry extends
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
async delete(relativePath, data, query, requestHeaders = {}) {
|
|
73
|
-
return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
AlgoHttpClientWithRetry.MAX_TRIES = 5;
|
|
77
|
-
AlgoHttpClientWithRetry.MAX_BACKOFF_MS = 10000;
|
|
78
|
-
// These lists come from https://visionmedia.github.io/superagent/#retrying-requests
|
|
79
|
-
// which is the underlying library used by algosdk - but the CloudFlare specific 52X status codes have been removed
|
|
80
|
-
AlgoHttpClientWithRetry.RETRY_STATUS_CODES = [408, 413, 429, 500, 502, 503, 504];
|
|
81
|
-
AlgoHttpClientWithRetry.RETRY_ERROR_CODES = [
|
|
82
|
-
'ETIMEDOUT',
|
|
83
|
-
'ECONNRESET',
|
|
84
|
-
'EADDRINUSE',
|
|
85
|
-
'ECONNREFUSED',
|
|
86
|
-
'EPIPE',
|
|
87
|
-
'ENOTFOUND',
|
|
88
|
-
'ENETUNREACH',
|
|
89
|
-
'EAI_AGAIN',
|
|
90
|
-
'EPROTO', // We get this intermittently with AlgoNode API
|
|
91
|
-
];
|
|
92
|
-
|
|
7
|
+
var AlgoHttpClientWithRetry = class AlgoHttpClientWithRetry extends algosdk_client.URLTokenBaseHTTPClient {
|
|
8
|
+
static MAX_TRIES = 5;
|
|
9
|
+
static MAX_BACKOFF_MS = 1e4;
|
|
10
|
+
static RETRY_STATUS_CODES = [
|
|
11
|
+
408,
|
|
12
|
+
413,
|
|
13
|
+
429,
|
|
14
|
+
500,
|
|
15
|
+
502,
|
|
16
|
+
503,
|
|
17
|
+
504
|
|
18
|
+
];
|
|
19
|
+
static RETRY_ERROR_CODES = [
|
|
20
|
+
"ETIMEDOUT",
|
|
21
|
+
"ECONNRESET",
|
|
22
|
+
"EADDRINUSE",
|
|
23
|
+
"ECONNREFUSED",
|
|
24
|
+
"EPIPE",
|
|
25
|
+
"ENOTFOUND",
|
|
26
|
+
"ENETUNREACH",
|
|
27
|
+
"EAI_AGAIN",
|
|
28
|
+
"EPROTO"
|
|
29
|
+
];
|
|
30
|
+
async callWithRetry(func) {
|
|
31
|
+
let response;
|
|
32
|
+
let numTries = 1;
|
|
33
|
+
do
|
|
34
|
+
try {
|
|
35
|
+
response = await func();
|
|
36
|
+
} catch (err) {
|
|
37
|
+
if (numTries >= AlgoHttpClientWithRetry.MAX_TRIES) throw err;
|
|
38
|
+
if (!(AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) || AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) || "response" in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))) throw err;
|
|
39
|
+
const delayTimeMs = numTries == 1 ? 0 : Math.min(1e3 * Math.pow(2, numTries - 1), AlgoHttpClientWithRetry.MAX_BACKOFF_MS);
|
|
40
|
+
if (delayTimeMs > 0) await new Promise((r) => setTimeout(r, delayTimeMs));
|
|
41
|
+
require_config.Config.logger.warn(`algosdk request failed ${numTries} times. Retrying in ${delayTimeMs}ms: ${err}`);
|
|
42
|
+
}
|
|
43
|
+
while (!response && ++numTries <= AlgoHttpClientWithRetry.MAX_TRIES);
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
async get(relativePath, query, requestHeaders = {}) {
|
|
47
|
+
const response = await this.callWithRetry(() => super.get(relativePath, query, requestHeaders));
|
|
48
|
+
if (relativePath.startsWith("/v2/accounts/") && relativePath.endsWith("/created-applications") && response.status === 200 && query?.["include-all"]?.toString() === "true") try {
|
|
49
|
+
const json = (0, algosdk.parseJSON)(Buffer.from(response.body).toString(), { intDecoding: algosdk.IntDecoding.MIXED });
|
|
50
|
+
if (json.applications) {
|
|
51
|
+
for (const app of json.applications) if (app.params) {
|
|
52
|
+
if (app.params["approval-program"] === null) app.params["approval-program"] = "";
|
|
53
|
+
if (app.params["clear-state-program"] === null) app.params["clear-state-program"] = "";
|
|
54
|
+
}
|
|
55
|
+
response.body = Buffer.from((0, algosdk.stringifyJSON)(json));
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
require_config.Config.logger.warn("Failed to fix indexer response for created applications", e);
|
|
59
|
+
}
|
|
60
|
+
return response;
|
|
61
|
+
}
|
|
62
|
+
async post(relativePath, data, query, requestHeaders = {}) {
|
|
63
|
+
return await this.callWithRetry(() => super.post(relativePath, data, query, requestHeaders));
|
|
64
|
+
}
|
|
65
|
+
async delete(relativePath, data, query, requestHeaders = {}) {
|
|
66
|
+
return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders));
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
93
70
|
exports.AlgoHttpClientWithRetry = AlgoHttpClientWithRetry;
|
|
94
|
-
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=algo-http-client-with-retry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"algo-http-client-with-retry.js","sources":["../../src/types/algo-http-client-with-retry.ts"],"sourcesContent":["import { IntDecoding, parseJSON, stringifyJSON } from 'algosdk'\nimport { BaseHTTPClientResponse, Query, URLTokenBaseHTTPClient } from 'algosdk/client'\nimport { Config } from '../config'\n\n/** A HTTP Client that wraps the Algorand SDK HTTP Client with retries */\nexport class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {\n private static readonly MAX_TRIES = 5\n private static readonly MAX_BACKOFF_MS = 10000\n\n // These lists come from https://visionmedia.github.io/superagent/#retrying-requests\n // which is the underlying library used by algosdk - but the CloudFlare specific 52X status codes have been removed\n private static readonly RETRY_STATUS_CODES = [408, 413, 429, 500, 502, 503, 504]\n private static readonly RETRY_ERROR_CODES = [\n 'ETIMEDOUT',\n 'ECONNRESET',\n 'EADDRINUSE',\n 'ECONNREFUSED',\n 'EPIPE',\n 'ENOTFOUND',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'EPROTO', // We get this intermittently with AlgoNode API\n ]\n\n private async callWithRetry(func: () => Promise<BaseHTTPClientResponse>): Promise<BaseHTTPClientResponse> {\n let response: BaseHTTPClientResponse | undefined\n let numTries = 1\n do {\n try {\n response = await func()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n if (numTries >= AlgoHttpClientWithRetry.MAX_TRIES) {\n throw err\n }\n // Only retry for one of the hardcoded conditions\n if (\n !(\n AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) ||\n AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) ||\n ('response' in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))\n )\n ) {\n throw err\n }\n // Retry immediately the first time, then exponentially backoff.\n const delayTimeMs = numTries == 1 ? 0 : Math.min(1000 * Math.pow(2, numTries - 1), AlgoHttpClientWithRetry.MAX_BACKOFF_MS)\n if (delayTimeMs > 0) {\n await new Promise((r) => setTimeout(r, delayTimeMs))\n }\n Config.logger.warn(`algosdk request failed ${numTries} times. Retrying in ${delayTimeMs}ms: ${err}`)\n }\n } while (!response && ++numTries <= AlgoHttpClientWithRetry.MAX_TRIES)\n return response!\n }\n\n async get(relativePath: string, query?: Query<string>, requestHeaders: Record<string, string> = {}): Promise<BaseHTTPClientResponse> {\n const response = await this.callWithRetry(() => super.get(relativePath, query, requestHeaders))\n if (\n relativePath.startsWith('/v2/accounts/') &&\n relativePath.endsWith('/created-applications') &&\n response.status === 200 &&\n query?.['include-all']?.toString() === 'true'\n ) {\n // todo: Temporary hack\n // Indexer get created applications by account returns approvalProgram and clearStateProgram as null, which breaks the algosdk@3 decoder\n // instead we will detect this call and set them to empty byte arrays\n try {\n const json = parseJSON(Buffer.from(response.body).toString(), { intDecoding: IntDecoding.MIXED })\n if (json.applications) {\n for (const app of json.applications) {\n if (app.params) {\n if (app.params['approval-program'] === null) {\n app.params['approval-program'] = ''\n }\n if (app.params['clear-state-program'] === null) {\n app.params['clear-state-program'] = ''\n }\n }\n }\n response.body = Buffer.from(stringifyJSON(json))\n }\n } catch (e) {\n // Make this hack resilient so we never break the app\n Config.logger.warn('Failed to fix indexer response for created applications', e)\n }\n }\n return response\n }\n\n async post(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.post(relativePath, data, query, requestHeaders))\n }\n\n async delete(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders))\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"algo-http-client-with-retry.js","names":["URLTokenBaseHTTPClient","IntDecoding"],"sources":["../../src/types/algo-http-client-with-retry.ts"],"sourcesContent":["import { IntDecoding, parseJSON, stringifyJSON } from 'algosdk'\nimport { BaseHTTPClientResponse, Query, URLTokenBaseHTTPClient } from 'algosdk/client'\nimport { Config } from '../config'\n\n/** A HTTP Client that wraps the Algorand SDK HTTP Client with retries */\nexport class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {\n private static readonly MAX_TRIES = 5\n private static readonly MAX_BACKOFF_MS = 10000\n\n // These lists come from https://visionmedia.github.io/superagent/#retrying-requests\n // which is the underlying library used by algosdk - but the CloudFlare specific 52X status codes have been removed\n private static readonly RETRY_STATUS_CODES = [408, 413, 429, 500, 502, 503, 504]\n private static readonly RETRY_ERROR_CODES = [\n 'ETIMEDOUT',\n 'ECONNRESET',\n 'EADDRINUSE',\n 'ECONNREFUSED',\n 'EPIPE',\n 'ENOTFOUND',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'EPROTO', // We get this intermittently with AlgoNode API\n ]\n\n private async callWithRetry(func: () => Promise<BaseHTTPClientResponse>): Promise<BaseHTTPClientResponse> {\n let response: BaseHTTPClientResponse | undefined\n let numTries = 1\n do {\n try {\n response = await func()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n if (numTries >= AlgoHttpClientWithRetry.MAX_TRIES) {\n throw err\n }\n // Only retry for one of the hardcoded conditions\n if (\n !(\n AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) ||\n AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) ||\n ('response' in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))\n )\n ) {\n throw err\n }\n // Retry immediately the first time, then exponentially backoff.\n const delayTimeMs = numTries == 1 ? 0 : Math.min(1000 * Math.pow(2, numTries - 1), AlgoHttpClientWithRetry.MAX_BACKOFF_MS)\n if (delayTimeMs > 0) {\n await new Promise((r) => setTimeout(r, delayTimeMs))\n }\n Config.logger.warn(`algosdk request failed ${numTries} times. Retrying in ${delayTimeMs}ms: ${err}`)\n }\n } while (!response && ++numTries <= AlgoHttpClientWithRetry.MAX_TRIES)\n return response!\n }\n\n async get(relativePath: string, query?: Query<string>, requestHeaders: Record<string, string> = {}): Promise<BaseHTTPClientResponse> {\n const response = await this.callWithRetry(() => super.get(relativePath, query, requestHeaders))\n if (\n relativePath.startsWith('/v2/accounts/') &&\n relativePath.endsWith('/created-applications') &&\n response.status === 200 &&\n query?.['include-all']?.toString() === 'true'\n ) {\n // todo: Temporary hack\n // Indexer get created applications by account returns approvalProgram and clearStateProgram as null, which breaks the algosdk@3 decoder\n // instead we will detect this call and set them to empty byte arrays\n try {\n const json = parseJSON(Buffer.from(response.body).toString(), { intDecoding: IntDecoding.MIXED })\n if (json.applications) {\n for (const app of json.applications) {\n if (app.params) {\n if (app.params['approval-program'] === null) {\n app.params['approval-program'] = ''\n }\n if (app.params['clear-state-program'] === null) {\n app.params['clear-state-program'] = ''\n }\n }\n }\n response.body = Buffer.from(stringifyJSON(json))\n }\n } catch (e) {\n // Make this hack resilient so we never break the app\n Config.logger.warn('Failed to fix indexer response for created applications', e)\n }\n }\n return response\n }\n\n async post(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.post(relativePath, data, query, requestHeaders))\n }\n\n async delete(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders))\n }\n}\n"],"mappings":";;;;;;AAKA,IAAa,0BAAb,MAAa,gCAAgCA,eAAAA,uBAAuB;CAClE,OAAwB,YAAY;CACpC,OAAwB,iBAAiB;CAIzC,OAAwB,qBAAqB;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;CAAG;CAC/E,OAAwB,oBAAoB;EAC1C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,MAAc,cAAc,MAA8E;EACxG,IAAI;EACJ,IAAI,WAAW;EACf;GACE,IAAI;IACF,WAAW,MAAM,KAAK;GAExB,SAAS,KAAU;IACjB,IAAI,YAAY,wBAAwB,WACtC,MAAM;IAGR,IACE,EACE,wBAAwB,kBAAkB,SAAS,IAAI,IAAI,KAC3D,wBAAwB,mBAAmB,SAAS,OAAO,IAAI,MAAM,CAAC,KACrE,cAAc,OAAO,wBAAwB,mBAAmB,SAAS,OAAO,IAAI,SAAS,MAAM,CAAC,IAGvG,MAAM;IAGR,MAAM,cAAc,YAAY,IAAI,IAAI,KAAK,IAAI,MAAO,KAAK,IAAI,GAAG,WAAW,CAAC,GAAG,wBAAwB,cAAc;IACzH,IAAI,cAAc,GAChB,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,WAAW,CAAC;IAErD,eAAA,OAAO,OAAO,KAAK,0BAA0B,SAAS,sBAAsB,YAAY,MAAM,KAAK;GACrG;SACO,CAAC,YAAY,EAAE,YAAY,wBAAwB;EAC5D,OAAO;CACT;CAEA,MAAM,IAAI,cAAsB,OAAuB,iBAAyC,CAAC,GAAoC;EACnI,MAAM,WAAW,MAAM,KAAK,oBAAoB,MAAM,IAAI,cAAc,OAAO,cAAc,CAAC;EAC9F,IACE,aAAa,WAAW,eAAe,KACvC,aAAa,SAAS,uBAAuB,KAC7C,SAAS,WAAW,OACpB,QAAQ,cAAc,EAAE,SAAS,MAAM,QAKvC,IAAI;GACF,MAAM,QAAA,GAAA,QAAA,UAAA,CAAiB,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,GAAG,EAAE,aAAaC,QAAAA,YAAY,MAAM,CAAC;GAChG,IAAI,KAAK,cAAc;IACrB,KAAK,MAAM,OAAO,KAAK,cACrB,IAAI,IAAI,QAAQ;KACd,IAAI,IAAI,OAAO,wBAAwB,MACrC,IAAI,OAAO,sBAAsB;KAEnC,IAAI,IAAI,OAAO,2BAA2B,MACxC,IAAI,OAAO,yBAAyB;IAExC;IAEF,SAAS,OAAO,OAAO,MAAA,GAAA,QAAA,cAAA,CAAmB,IAAI,CAAC;GACjD;EACF,SAAS,GAAG;GAEV,eAAA,OAAO,OAAO,KAAK,2DAA2D,CAAC;EACjF;EAEF,OAAO;CACT;CAEA,MAAM,KACJ,cACA,MACA,OACA,iBAAyC,CAAC,GACT;EACjC,OAAO,MAAM,KAAK,oBAAoB,MAAM,KAAK,cAAc,MAAM,OAAO,cAAc,CAAC;CAC7F;CAEA,MAAM,OACJ,cACA,MACA,OACA,iBAAyC,CAAC,GACT;EACjC,OAAO,MAAM,KAAK,oBAAoB,MAAM,OAAO,cAAc,MAAM,OAAO,cAAc,CAAC;CAC/F;AACF"}
|
|
@@ -1,92 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Config } from "../config.mjs";
|
|
2
|
+
import { IntDecoding, parseJSON, stringifyJSON } from "algosdk";
|
|
3
|
+
import { URLTokenBaseHTTPClient } from "algosdk/client";
|
|
4
|
+
//#region src/types/algo-http-client-with-retry.ts
|
|
5
5
|
/** A HTTP Client that wraps the Algorand SDK HTTP Client with retries */
|
|
6
|
-
class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
async delete(relativePath, data, query, requestHeaders = {}) {
|
|
71
|
-
return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders));
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
AlgoHttpClientWithRetry.MAX_TRIES = 5;
|
|
75
|
-
AlgoHttpClientWithRetry.MAX_BACKOFF_MS = 10000;
|
|
76
|
-
// These lists come from https://visionmedia.github.io/superagent/#retrying-requests
|
|
77
|
-
// which is the underlying library used by algosdk - but the CloudFlare specific 52X status codes have been removed
|
|
78
|
-
AlgoHttpClientWithRetry.RETRY_STATUS_CODES = [408, 413, 429, 500, 502, 503, 504];
|
|
79
|
-
AlgoHttpClientWithRetry.RETRY_ERROR_CODES = [
|
|
80
|
-
'ETIMEDOUT',
|
|
81
|
-
'ECONNRESET',
|
|
82
|
-
'EADDRINUSE',
|
|
83
|
-
'ECONNREFUSED',
|
|
84
|
-
'EPIPE',
|
|
85
|
-
'ENOTFOUND',
|
|
86
|
-
'ENETUNREACH',
|
|
87
|
-
'EAI_AGAIN',
|
|
88
|
-
'EPROTO', // We get this intermittently with AlgoNode API
|
|
89
|
-
];
|
|
90
|
-
|
|
6
|
+
var AlgoHttpClientWithRetry = class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {
|
|
7
|
+
static MAX_TRIES = 5;
|
|
8
|
+
static MAX_BACKOFF_MS = 1e4;
|
|
9
|
+
static RETRY_STATUS_CODES = [
|
|
10
|
+
408,
|
|
11
|
+
413,
|
|
12
|
+
429,
|
|
13
|
+
500,
|
|
14
|
+
502,
|
|
15
|
+
503,
|
|
16
|
+
504
|
|
17
|
+
];
|
|
18
|
+
static RETRY_ERROR_CODES = [
|
|
19
|
+
"ETIMEDOUT",
|
|
20
|
+
"ECONNRESET",
|
|
21
|
+
"EADDRINUSE",
|
|
22
|
+
"ECONNREFUSED",
|
|
23
|
+
"EPIPE",
|
|
24
|
+
"ENOTFOUND",
|
|
25
|
+
"ENETUNREACH",
|
|
26
|
+
"EAI_AGAIN",
|
|
27
|
+
"EPROTO"
|
|
28
|
+
];
|
|
29
|
+
async callWithRetry(func) {
|
|
30
|
+
let response;
|
|
31
|
+
let numTries = 1;
|
|
32
|
+
do
|
|
33
|
+
try {
|
|
34
|
+
response = await func();
|
|
35
|
+
} catch (err) {
|
|
36
|
+
if (numTries >= AlgoHttpClientWithRetry.MAX_TRIES) throw err;
|
|
37
|
+
if (!(AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) || AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) || "response" in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))) throw err;
|
|
38
|
+
const delayTimeMs = numTries == 1 ? 0 : Math.min(1e3 * Math.pow(2, numTries - 1), AlgoHttpClientWithRetry.MAX_BACKOFF_MS);
|
|
39
|
+
if (delayTimeMs > 0) await new Promise((r) => setTimeout(r, delayTimeMs));
|
|
40
|
+
Config.logger.warn(`algosdk request failed ${numTries} times. Retrying in ${delayTimeMs}ms: ${err}`);
|
|
41
|
+
}
|
|
42
|
+
while (!response && ++numTries <= AlgoHttpClientWithRetry.MAX_TRIES);
|
|
43
|
+
return response;
|
|
44
|
+
}
|
|
45
|
+
async get(relativePath, query, requestHeaders = {}) {
|
|
46
|
+
const response = await this.callWithRetry(() => super.get(relativePath, query, requestHeaders));
|
|
47
|
+
if (relativePath.startsWith("/v2/accounts/") && relativePath.endsWith("/created-applications") && response.status === 200 && query?.["include-all"]?.toString() === "true") try {
|
|
48
|
+
const json = parseJSON(Buffer.from(response.body).toString(), { intDecoding: IntDecoding.MIXED });
|
|
49
|
+
if (json.applications) {
|
|
50
|
+
for (const app of json.applications) if (app.params) {
|
|
51
|
+
if (app.params["approval-program"] === null) app.params["approval-program"] = "";
|
|
52
|
+
if (app.params["clear-state-program"] === null) app.params["clear-state-program"] = "";
|
|
53
|
+
}
|
|
54
|
+
response.body = Buffer.from(stringifyJSON(json));
|
|
55
|
+
}
|
|
56
|
+
} catch (e) {
|
|
57
|
+
Config.logger.warn("Failed to fix indexer response for created applications", e);
|
|
58
|
+
}
|
|
59
|
+
return response;
|
|
60
|
+
}
|
|
61
|
+
async post(relativePath, data, query, requestHeaders = {}) {
|
|
62
|
+
return await this.callWithRetry(() => super.post(relativePath, data, query, requestHeaders));
|
|
63
|
+
}
|
|
64
|
+
async delete(relativePath, data, query, requestHeaders = {}) {
|
|
65
|
+
return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders));
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
//#endregion
|
|
91
69
|
export { AlgoHttpClientWithRetry };
|
|
92
|
-
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=algo-http-client-with-retry.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"algo-http-client-with-retry.mjs","sources":["../../src/types/algo-http-client-with-retry.ts"],"sourcesContent":["import { IntDecoding, parseJSON, stringifyJSON } from 'algosdk'\nimport { BaseHTTPClientResponse, Query, URLTokenBaseHTTPClient } from 'algosdk/client'\nimport { Config } from '../config'\n\n/** A HTTP Client that wraps the Algorand SDK HTTP Client with retries */\nexport class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {\n private static readonly MAX_TRIES = 5\n private static readonly MAX_BACKOFF_MS = 10000\n\n // These lists come from https://visionmedia.github.io/superagent/#retrying-requests\n // which is the underlying library used by algosdk - but the CloudFlare specific 52X status codes have been removed\n private static readonly RETRY_STATUS_CODES = [408, 413, 429, 500, 502, 503, 504]\n private static readonly RETRY_ERROR_CODES = [\n 'ETIMEDOUT',\n 'ECONNRESET',\n 'EADDRINUSE',\n 'ECONNREFUSED',\n 'EPIPE',\n 'ENOTFOUND',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'EPROTO', // We get this intermittently with AlgoNode API\n ]\n\n private async callWithRetry(func: () => Promise<BaseHTTPClientResponse>): Promise<BaseHTTPClientResponse> {\n let response: BaseHTTPClientResponse | undefined\n let numTries = 1\n do {\n try {\n response = await func()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n if (numTries >= AlgoHttpClientWithRetry.MAX_TRIES) {\n throw err\n }\n // Only retry for one of the hardcoded conditions\n if (\n !(\n AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) ||\n AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) ||\n ('response' in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))\n )\n ) {\n throw err\n }\n // Retry immediately the first time, then exponentially backoff.\n const delayTimeMs = numTries == 1 ? 0 : Math.min(1000 * Math.pow(2, numTries - 1), AlgoHttpClientWithRetry.MAX_BACKOFF_MS)\n if (delayTimeMs > 0) {\n await new Promise((r) => setTimeout(r, delayTimeMs))\n }\n Config.logger.warn(`algosdk request failed ${numTries} times. Retrying in ${delayTimeMs}ms: ${err}`)\n }\n } while (!response && ++numTries <= AlgoHttpClientWithRetry.MAX_TRIES)\n return response!\n }\n\n async get(relativePath: string, query?: Query<string>, requestHeaders: Record<string, string> = {}): Promise<BaseHTTPClientResponse> {\n const response = await this.callWithRetry(() => super.get(relativePath, query, requestHeaders))\n if (\n relativePath.startsWith('/v2/accounts/') &&\n relativePath.endsWith('/created-applications') &&\n response.status === 200 &&\n query?.['include-all']?.toString() === 'true'\n ) {\n // todo: Temporary hack\n // Indexer get created applications by account returns approvalProgram and clearStateProgram as null, which breaks the algosdk@3 decoder\n // instead we will detect this call and set them to empty byte arrays\n try {\n const json = parseJSON(Buffer.from(response.body).toString(), { intDecoding: IntDecoding.MIXED })\n if (json.applications) {\n for (const app of json.applications) {\n if (app.params) {\n if (app.params['approval-program'] === null) {\n app.params['approval-program'] = ''\n }\n if (app.params['clear-state-program'] === null) {\n app.params['clear-state-program'] = ''\n }\n }\n }\n response.body = Buffer.from(stringifyJSON(json))\n }\n } catch (e) {\n // Make this hack resilient so we never break the app\n Config.logger.warn('Failed to fix indexer response for created applications', e)\n }\n }\n return response\n }\n\n async post(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.post(relativePath, data, query, requestHeaders))\n }\n\n async delete(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders))\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"algo-http-client-with-retry.mjs","names":[],"sources":["../../src/types/algo-http-client-with-retry.ts"],"sourcesContent":["import { IntDecoding, parseJSON, stringifyJSON } from 'algosdk'\nimport { BaseHTTPClientResponse, Query, URLTokenBaseHTTPClient } from 'algosdk/client'\nimport { Config } from '../config'\n\n/** A HTTP Client that wraps the Algorand SDK HTTP Client with retries */\nexport class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {\n private static readonly MAX_TRIES = 5\n private static readonly MAX_BACKOFF_MS = 10000\n\n // These lists come from https://visionmedia.github.io/superagent/#retrying-requests\n // which is the underlying library used by algosdk - but the CloudFlare specific 52X status codes have been removed\n private static readonly RETRY_STATUS_CODES = [408, 413, 429, 500, 502, 503, 504]\n private static readonly RETRY_ERROR_CODES = [\n 'ETIMEDOUT',\n 'ECONNRESET',\n 'EADDRINUSE',\n 'ECONNREFUSED',\n 'EPIPE',\n 'ENOTFOUND',\n 'ENETUNREACH',\n 'EAI_AGAIN',\n 'EPROTO', // We get this intermittently with AlgoNode API\n ]\n\n private async callWithRetry(func: () => Promise<BaseHTTPClientResponse>): Promise<BaseHTTPClientResponse> {\n let response: BaseHTTPClientResponse | undefined\n let numTries = 1\n do {\n try {\n response = await func()\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n if (numTries >= AlgoHttpClientWithRetry.MAX_TRIES) {\n throw err\n }\n // Only retry for one of the hardcoded conditions\n if (\n !(\n AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) ||\n AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) ||\n ('response' in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))\n )\n ) {\n throw err\n }\n // Retry immediately the first time, then exponentially backoff.\n const delayTimeMs = numTries == 1 ? 0 : Math.min(1000 * Math.pow(2, numTries - 1), AlgoHttpClientWithRetry.MAX_BACKOFF_MS)\n if (delayTimeMs > 0) {\n await new Promise((r) => setTimeout(r, delayTimeMs))\n }\n Config.logger.warn(`algosdk request failed ${numTries} times. Retrying in ${delayTimeMs}ms: ${err}`)\n }\n } while (!response && ++numTries <= AlgoHttpClientWithRetry.MAX_TRIES)\n return response!\n }\n\n async get(relativePath: string, query?: Query<string>, requestHeaders: Record<string, string> = {}): Promise<BaseHTTPClientResponse> {\n const response = await this.callWithRetry(() => super.get(relativePath, query, requestHeaders))\n if (\n relativePath.startsWith('/v2/accounts/') &&\n relativePath.endsWith('/created-applications') &&\n response.status === 200 &&\n query?.['include-all']?.toString() === 'true'\n ) {\n // todo: Temporary hack\n // Indexer get created applications by account returns approvalProgram and clearStateProgram as null, which breaks the algosdk@3 decoder\n // instead we will detect this call and set them to empty byte arrays\n try {\n const json = parseJSON(Buffer.from(response.body).toString(), { intDecoding: IntDecoding.MIXED })\n if (json.applications) {\n for (const app of json.applications) {\n if (app.params) {\n if (app.params['approval-program'] === null) {\n app.params['approval-program'] = ''\n }\n if (app.params['clear-state-program'] === null) {\n app.params['clear-state-program'] = ''\n }\n }\n }\n response.body = Buffer.from(stringifyJSON(json))\n }\n } catch (e) {\n // Make this hack resilient so we never break the app\n Config.logger.warn('Failed to fix indexer response for created applications', e)\n }\n }\n return response\n }\n\n async post(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.post(relativePath, data, query, requestHeaders))\n }\n\n async delete(\n relativePath: string,\n data: Uint8Array,\n query?: Query<string>,\n requestHeaders: Record<string, string> = {},\n ): Promise<BaseHTTPClientResponse> {\n return await this.callWithRetry(() => super.delete(relativePath, data, query, requestHeaders))\n }\n}\n"],"mappings":";;;;;AAKA,IAAa,0BAAb,MAAa,gCAAgC,uBAAuB;CAClE,OAAwB,YAAY;CACpC,OAAwB,iBAAiB;CAIzC,OAAwB,qBAAqB;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;CAAG;CAC/E,OAAwB,oBAAoB;EAC1C;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,MAAc,cAAc,MAA8E;EACxG,IAAI;EACJ,IAAI,WAAW;EACf;GACE,IAAI;IACF,WAAW,MAAM,KAAK;GAExB,SAAS,KAAU;IACjB,IAAI,YAAY,wBAAwB,WACtC,MAAM;IAGR,IACE,EACE,wBAAwB,kBAAkB,SAAS,IAAI,IAAI,KAC3D,wBAAwB,mBAAmB,SAAS,OAAO,IAAI,MAAM,CAAC,KACrE,cAAc,OAAO,wBAAwB,mBAAmB,SAAS,OAAO,IAAI,SAAS,MAAM,CAAC,IAGvG,MAAM;IAGR,MAAM,cAAc,YAAY,IAAI,IAAI,KAAK,IAAI,MAAO,KAAK,IAAI,GAAG,WAAW,CAAC,GAAG,wBAAwB,cAAc;IACzH,IAAI,cAAc,GAChB,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,WAAW,CAAC;IAErD,OAAO,OAAO,KAAK,0BAA0B,SAAS,sBAAsB,YAAY,MAAM,KAAK;GACrG;SACO,CAAC,YAAY,EAAE,YAAY,wBAAwB;EAC5D,OAAO;CACT;CAEA,MAAM,IAAI,cAAsB,OAAuB,iBAAyC,CAAC,GAAoC;EACnI,MAAM,WAAW,MAAM,KAAK,oBAAoB,MAAM,IAAI,cAAc,OAAO,cAAc,CAAC;EAC9F,IACE,aAAa,WAAW,eAAe,KACvC,aAAa,SAAS,uBAAuB,KAC7C,SAAS,WAAW,OACpB,QAAQ,cAAc,EAAE,SAAS,MAAM,QAKvC,IAAI;GACF,MAAM,OAAO,UAAU,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,GAAG,EAAE,aAAa,YAAY,MAAM,CAAC;GAChG,IAAI,KAAK,cAAc;IACrB,KAAK,MAAM,OAAO,KAAK,cACrB,IAAI,IAAI,QAAQ;KACd,IAAI,IAAI,OAAO,wBAAwB,MACrC,IAAI,OAAO,sBAAsB;KAEnC,IAAI,IAAI,OAAO,2BAA2B,MACxC,IAAI,OAAO,yBAAyB;IAExC;IAEF,SAAS,OAAO,OAAO,KAAK,cAAc,IAAI,CAAC;GACjD;EACF,SAAS,GAAG;GAEV,OAAO,OAAO,KAAK,2DAA2D,CAAC;EACjF;EAEF,OAAO;CACT;CAEA,MAAM,KACJ,cACA,MACA,OACA,iBAAyC,CAAC,GACT;EACjC,OAAO,MAAM,KAAK,oBAAoB,MAAM,KAAK,cAAc,MAAM,OAAO,cAAc,CAAC;CAC7F;CAEA,MAAM,OACJ,cACA,MACA,OACA,iBAAyC,CAAC,GACT;EACjC,OAAO,MAAM,KAAK,oBAAoB,MAAM,OAAO,cAAc,MAAM,OAAO,cAAc,CAAC;CAC/F;AACF"}
|