@augustdigital/sdk 4.27.3 → 5.1.0
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/LICENSE +21 -0
- package/README.md +58 -0
- package/lib/core/analytics/sanitize.d.ts +3 -0
- package/lib/core/analytics/sanitize.js +74 -0
- package/lib/core/analytics/sentry.d.ts +1 -1
- package/lib/core/analytics/sentry.js +4 -1
- package/lib/core/auth/verify.js +9 -4
- package/lib/core/base.class.d.ts +5 -1
- package/lib/core/base.class.js +19 -2
- package/lib/core/errors/index.d.ts +40 -0
- package/lib/core/errors/index.js +103 -0
- package/lib/core/fetcher.d.ts +2 -0
- package/lib/core/fetcher.js +149 -41
- package/lib/core/helpers/web3.d.ts +3 -3
- package/lib/core/helpers/web3.js +45 -9
- package/lib/core/index.d.ts +2 -0
- package/lib/core/index.js +2 -0
- package/lib/core/logger/index.d.ts +10 -0
- package/lib/core/logger/index.js +37 -4
- package/lib/core/logger/slack.js +6 -2
- package/lib/core/version-check.d.ts +6 -0
- package/lib/core/version-check.js +101 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -7
- package/lib/main.d.ts +7 -2
- package/lib/main.js +5 -2
- package/lib/modules/vaults/getters.d.ts +5 -1
- package/lib/modules/vaults/getters.js +44 -23
- package/lib/modules/vaults/main.d.ts +7 -1
- package/lib/modules/vaults/main.js +30 -1
- package/lib/polyfills.d.ts +1 -0
- package/lib/polyfills.js +10 -0
- package/package.json +14 -5
- package/lib/abis/AddressResolver.js.map +0 -1
- package/lib/abis/ChainlinkV3.js.map +0 -1
- package/lib/abis/ERC20.js.map +0 -1
- package/lib/abis/ERC20_Bytes32.js.map +0 -1
- package/lib/abis/ERC4626.js.map +0 -1
- package/lib/abis/ERC721.js.map +0 -1
- package/lib/abis/FeeOracle.js.map +0 -1
- package/lib/abis/LendingPool.js.map +0 -1
- package/lib/abis/LendingPoolV2.js.map +0 -1
- package/lib/abis/LendingPoolV3.js.map +0 -1
- package/lib/abis/Loan.js.map +0 -1
- package/lib/abis/MultiAssetNativeDepositWrapper.js.map +0 -1
- package/lib/abis/Multicall3.js.map +0 -1
- package/lib/abis/OFT.js.map +0 -1
- package/lib/abis/PoolAdapter.js.map +0 -1
- package/lib/abis/RewardDistributor.js.map +0 -1
- package/lib/abis/RwaRedeemSubaccount.js.map +0 -1
- package/lib/abis/SmartAccount.js.map +0 -1
- package/lib/abis/TextResolver.js.map +0 -1
- package/lib/abis/TokenizedVaultV2.js.map +0 -1
- package/lib/abis/TokenizedVaultV2DepositWithPermit.js.map +0 -1
- package/lib/abis/TokenizedVaultV2Receipt.js.map +0 -1
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js.map +0 -1
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js.map +0 -1
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.js.map +0 -1
- package/lib/abis/UniversalResolverResolve.js.map +0 -1
- package/lib/abis/UniversalSignatureValidator.js.map +0 -1
- package/lib/abis/WrapperAdapter.js.map +0 -1
- package/lib/abis/index.js.map +0 -1
- package/lib/adapters/evm/getters.js.map +0 -1
- package/lib/adapters/evm/index.js.map +0 -1
- package/lib/adapters/evm/utils.js.map +0 -1
- package/lib/adapters/solana/constants.js.map +0 -1
- package/lib/adapters/solana/getters.js.map +0 -1
- package/lib/adapters/solana/idl/vault-idl.js.map +0 -1
- package/lib/adapters/solana/index.js.map +0 -1
- package/lib/adapters/solana/types.js.map +0 -1
- package/lib/adapters/solana/utils.js.map +0 -1
- package/lib/adapters/solana/vault.actions.js.map +0 -1
- package/lib/adapters/stellar/actions.js.map +0 -1
- package/lib/adapters/stellar/constants.js.map +0 -1
- package/lib/adapters/stellar/getters.js.map +0 -1
- package/lib/adapters/stellar/index.js.map +0 -1
- package/lib/adapters/stellar/soroban.js.map +0 -1
- package/lib/adapters/stellar/submit.js.map +0 -1
- package/lib/adapters/stellar/types.js.map +0 -1
- package/lib/adapters/stellar/utils.js.map +0 -1
- package/lib/adapters/sui/constants.js.map +0 -1
- package/lib/adapters/sui/getters.js.map +0 -1
- package/lib/adapters/sui/index.js.map +0 -1
- package/lib/adapters/sui/transformer.js.map +0 -1
- package/lib/adapters/sui/types.js.map +0 -1
- package/lib/adapters/sui/utils.js.map +0 -1
- package/lib/core/analytics/constants.js.map +0 -1
- package/lib/core/analytics/index.js.map +0 -1
- package/lib/core/analytics/instrumentation.js.map +0 -1
- package/lib/core/analytics/metrics.js.map +0 -1
- package/lib/core/analytics/sanitize.js.map +0 -1
- package/lib/core/analytics/sentry.js.map +0 -1
- package/lib/core/analytics/types.js.map +0 -1
- package/lib/core/analytics/user-identity.js.map +0 -1
- package/lib/core/auth/index.js.map +0 -1
- package/lib/core/auth/verify.js.map +0 -1
- package/lib/core/base.class.js.map +0 -1
- package/lib/core/constants/adapters.js.map +0 -1
- package/lib/core/constants/core.js.map +0 -1
- package/lib/core/constants/vaults.js.map +0 -1
- package/lib/core/constants/web3.js.map +0 -1
- package/lib/core/fetcher.js.map +0 -1
- package/lib/core/helpers/adapters.js.map +0 -1
- package/lib/core/helpers/core.js.map +0 -1
- package/lib/core/helpers/signer.js.map +0 -1
- package/lib/core/helpers/vaults.js.map +0 -1
- package/lib/core/helpers/web3.js.map +0 -1
- package/lib/core/index.js.map +0 -1
- package/lib/core/logger/index.js.map +0 -1
- package/lib/core/logger/slack.js.map +0 -1
- package/lib/evm/index.js.map +0 -1
- package/lib/evm/methods/crossChainVault.js.map +0 -1
- package/lib/evm/methods/index.js.map +0 -1
- package/lib/evm/types/crossChain.js.map +0 -1
- package/lib/evm/types/index.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/main.js.map +0 -1
- package/lib/modules/sub-accounts/fetcher.js.map +0 -1
- package/lib/modules/sub-accounts/index.js.map +0 -1
- package/lib/modules/sub-accounts/main.js.map +0 -1
- package/lib/modules/sub-accounts/utils.js.map +0 -1
- package/lib/modules/vaults/adapter.helpers.js.map +0 -1
- package/lib/modules/vaults/fetcher.js.map +0 -1
- package/lib/modules/vaults/getters.js.map +0 -1
- package/lib/modules/vaults/index.js.map +0 -1
- package/lib/modules/vaults/main.js.map +0 -1
- package/lib/modules/vaults/read.actions.js.map +0 -1
- package/lib/modules/vaults/types.js.map +0 -1
- package/lib/modules/vaults/utils/call-data-decoder.js.map +0 -1
- package/lib/modules/vaults/utils/date-utils.js.map +0 -1
- package/lib/modules/vaults/utils.js.map +0 -1
- package/lib/modules/vaults/write.actions.js.map +0 -1
- package/lib/services/coingecko/fetcher.js.map +0 -1
- package/lib/services/coingecko/index.js.map +0 -1
- package/lib/services/coingecko/utils.js.map +0 -1
- package/lib/services/debank/fetcher.js.map +0 -1
- package/lib/services/debank/index.js.map +0 -1
- package/lib/services/debank/utils.js.map +0 -1
- package/lib/services/layerzero/deposits.js.map +0 -1
- package/lib/services/layerzero/redeems.js.map +0 -1
- package/lib/services/layerzero/utils.js.map +0 -1
- package/lib/services/octavfi/fetcher.js.map +0 -1
- package/lib/services/octavfi/index.js.map +0 -1
- package/lib/services/octavfi/types.js.map +0 -1
- package/lib/services/octavfi/utils.js.map +0 -1
- package/lib/services/subgraph/fetcher.js.map +0 -1
- package/lib/services/subgraph/index.js.map +0 -1
- package/lib/services/subgraph/vaults.js.map +0 -1
- package/lib/types/index.js.map +0 -1
- package/lib/types/points.js.map +0 -1
- package/lib/types/pools.js.map +0 -1
- package/lib/types/staking.js.map +0 -1
- package/lib/types/sub-accounts.js.map +0 -1
- package/lib/types/subgraph.js.map +0 -1
- package/lib/types/typed-contract.js.map +0 -1
- package/lib/types/user.js.map +0 -1
- package/lib/types/vaults.js.map +0 -1
- package/lib/types/web3.js.map +0 -1
- package/lib/types/webserver.js.map +0 -1
package/lib/core/fetcher.js
CHANGED
|
@@ -26,6 +26,71 @@ const web3_1 = require("./helpers/web3");
|
|
|
26
26
|
const core_2 = require("./constants/core");
|
|
27
27
|
const vaults_1 = require("./helpers/vaults");
|
|
28
28
|
const analytics_1 = require("./analytics");
|
|
29
|
+
const sanitize_1 = require("./analytics/sanitize");
|
|
30
|
+
const errors_1 = require("./errors");
|
|
31
|
+
function errorFromResponseStatus(status, message, options) {
|
|
32
|
+
if (status === 401) {
|
|
33
|
+
return new errors_1.AugustAuthError('AUTH_UNAUTHORIZED', message, options);
|
|
34
|
+
}
|
|
35
|
+
if (status === 403) {
|
|
36
|
+
return new errors_1.AugustAuthError('AUTH_FORBIDDEN', message, options);
|
|
37
|
+
}
|
|
38
|
+
if (status === 429) {
|
|
39
|
+
return new errors_1.AugustRateLimitError(message, options);
|
|
40
|
+
}
|
|
41
|
+
return new errors_1.AugustServerError(status, message, options);
|
|
42
|
+
}
|
|
43
|
+
function buildRequestAbortSignal(options) {
|
|
44
|
+
const timeoutMs = options?.timeoutMs ?? core_2.REQUEST_TIMEOUT_MS;
|
|
45
|
+
const timeoutController = new AbortController();
|
|
46
|
+
let didTimeout = false;
|
|
47
|
+
const timeoutId = setTimeout(() => {
|
|
48
|
+
didTimeout = true;
|
|
49
|
+
timeoutController.abort();
|
|
50
|
+
}, timeoutMs);
|
|
51
|
+
let signal = timeoutController.signal;
|
|
52
|
+
let relayCleanup = () => { };
|
|
53
|
+
if (options?.signal) {
|
|
54
|
+
if (typeof AbortSignal.any === 'function') {
|
|
55
|
+
signal = AbortSignal.any([timeoutController.signal, options.signal]);
|
|
56
|
+
}
|
|
57
|
+
else if (options.signal.aborted) {
|
|
58
|
+
timeoutController.abort();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const relay = () => timeoutController.abort();
|
|
62
|
+
options.signal.addEventListener('abort', relay, { once: true });
|
|
63
|
+
relayCleanup = () => options.signal.removeEventListener('abort', relay);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
signal,
|
|
68
|
+
timeoutId,
|
|
69
|
+
timeoutMs,
|
|
70
|
+
timedOut: () => didTimeout,
|
|
71
|
+
cleanup: () => {
|
|
72
|
+
clearTimeout(timeoutId);
|
|
73
|
+
relayCleanup();
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
let _overrideDeprecationWarned = false;
|
|
78
|
+
function warnOverrideDeprecation(callerTag) {
|
|
79
|
+
if (_overrideDeprecationWarned)
|
|
80
|
+
return;
|
|
81
|
+
_overrideDeprecationWarned = true;
|
|
82
|
+
console.warn(`[@augustdigital/sdk] ${callerTag}: option "override" is deprecated and will be removed in a future major version. Pass a valid apiKey instead.`);
|
|
83
|
+
}
|
|
84
|
+
function readResponseHeader(headers, name) {
|
|
85
|
+
if (!headers)
|
|
86
|
+
return undefined;
|
|
87
|
+
const h = headers;
|
|
88
|
+
if (typeof h.get === 'function') {
|
|
89
|
+
return h.get(name) ?? undefined;
|
|
90
|
+
}
|
|
91
|
+
const v = headers[name];
|
|
92
|
+
return typeof v === 'string' ? v : undefined;
|
|
93
|
+
}
|
|
29
94
|
exports.CACHE = new lru_cache_1.LRUCache({
|
|
30
95
|
max: 1000,
|
|
31
96
|
ttl: 1000 * 60 * 60 * 24,
|
|
@@ -57,52 +122,85 @@ const PRICE_ERROR_CACHE = new lru_cache_1.LRUCache({
|
|
|
57
122
|
allowStale: false,
|
|
58
123
|
});
|
|
59
124
|
const PRICE_REQUESTS = new Map();
|
|
125
|
+
function buildAugustUrl(server, relativeUrl) {
|
|
126
|
+
const serverKey = server;
|
|
127
|
+
const base = core_2.WEBSERVER_URL[serverKey];
|
|
128
|
+
if (!base) {
|
|
129
|
+
throw new errors_1.AugustValidationError('INVALID_URL', `Unknown August server "${String(server)}". Expected one of: ${Object.keys(core_2.WEBSERVER_URL).join(', ')}`);
|
|
130
|
+
}
|
|
131
|
+
if (typeof relativeUrl !== 'string' || relativeUrl.length === 0) {
|
|
132
|
+
throw new errors_1.AugustValidationError('INVALID_URL', 'relativeUrl must be a non-empty string');
|
|
133
|
+
}
|
|
134
|
+
if (/^\s*[a-z][a-z0-9+.-]*:|^\s*\/\//i.test(relativeUrl)) {
|
|
135
|
+
throw new errors_1.AugustValidationError('INVALID_URL', `relativeUrl must be a path, not an absolute or protocol-relative URL`);
|
|
136
|
+
}
|
|
137
|
+
const candidate = `${base}${relativeUrl}`;
|
|
138
|
+
let url;
|
|
139
|
+
try {
|
|
140
|
+
url = new URL(candidate);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
throw new errors_1.AugustValidationError('INVALID_URL', `Invalid URL path: ${(0, sanitize_1.sanitizeString)(relativeUrl)}`);
|
|
144
|
+
}
|
|
145
|
+
const baseOrigin = new URL(base).origin;
|
|
146
|
+
if (url.origin !== baseOrigin) {
|
|
147
|
+
throw new errors_1.AugustValidationError('INVALID_URL', `URL origin mismatch: refusing to fetch ${url.origin} from a "${serverKey}" request scoped to ${baseOrigin}`);
|
|
148
|
+
}
|
|
149
|
+
return url.toString();
|
|
150
|
+
}
|
|
60
151
|
async function fetchAugustWithKey(apiKey, relativeUrl, options) {
|
|
152
|
+
if (options?.override) {
|
|
153
|
+
warnOverrideDeprecation('fetchAugustWithKey');
|
|
154
|
+
}
|
|
61
155
|
if (!apiKey && !options?.override) {
|
|
62
|
-
|
|
156
|
+
throw new errors_1.AugustAuthError('AUTH_MISSING_KEY', 'fetchAugustWithKey: apiKey is required (set keys.august on the SDK constructor, or pass an explicit apiKey).');
|
|
63
157
|
}
|
|
64
158
|
const defaultHeaders = {
|
|
65
159
|
'x-api-key': apiKey,
|
|
66
160
|
'content-type': 'application/json',
|
|
67
161
|
accept: 'application/json',
|
|
68
162
|
};
|
|
69
|
-
const
|
|
70
|
-
const timeoutId = setTimeout(() => controller.abort(), core_2.REQUEST_TIMEOUT_MS);
|
|
163
|
+
const { signal: requestSignal, timeoutMs: effectiveTimeoutMs, timedOut, cleanup, } = buildRequestAbortSignal(options);
|
|
71
164
|
const startTime = performance.now();
|
|
72
165
|
const server = options?.server || 'production';
|
|
73
166
|
try {
|
|
74
|
-
const
|
|
167
|
+
const safeUrl = buildAugustUrl(server, relativeUrl);
|
|
168
|
+
const res = await fetch(safeUrl, {
|
|
75
169
|
headers: {
|
|
76
170
|
...defaultHeaders,
|
|
77
171
|
...options?.headers,
|
|
78
172
|
},
|
|
79
173
|
method: options?.method ?? 'GET',
|
|
80
174
|
body: JSON.stringify(options?.data),
|
|
81
|
-
signal:
|
|
175
|
+
signal: requestSignal,
|
|
82
176
|
});
|
|
83
|
-
|
|
177
|
+
cleanup();
|
|
84
178
|
(0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, res.status, server);
|
|
85
|
-
const correlationId = res.headers
|
|
179
|
+
const correlationId = readResponseHeader(res.headers, 'x-correlation-id');
|
|
86
180
|
const logger = logger_1.Logger.getLogger();
|
|
87
181
|
if (!res.ok || res.status !== 200) {
|
|
88
182
|
if (correlationId && logger) {
|
|
89
183
|
logger.setTag('correlation_id', correlationId);
|
|
90
184
|
}
|
|
91
|
-
const error =
|
|
185
|
+
const error = errorFromResponseStatus(res.status, `Request failed: ${res.status}`, { correlationId });
|
|
92
186
|
logger?.captureException(error, { correlationId, status: res.status });
|
|
93
187
|
throw error;
|
|
94
188
|
}
|
|
95
189
|
return res;
|
|
96
190
|
}
|
|
97
191
|
catch (error) {
|
|
98
|
-
|
|
192
|
+
cleanup();
|
|
99
193
|
(0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, 0, server);
|
|
100
|
-
|
|
101
|
-
|
|
194
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
195
|
+
if (err.name === 'AbortError') {
|
|
196
|
+
if (!timedOut()) {
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
199
|
+
const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
|
|
102
200
|
logger_1.Logger.log.error('fetchAugustWithKey', timeoutError, { relativeUrl });
|
|
103
201
|
throw timeoutError;
|
|
104
202
|
}
|
|
105
|
-
throw
|
|
203
|
+
throw err;
|
|
106
204
|
}
|
|
107
205
|
}
|
|
108
206
|
async function fetchAugustPublic(relativeUrl, options) {
|
|
@@ -110,42 +208,46 @@ async function fetchAugustPublic(relativeUrl, options) {
|
|
|
110
208
|
'content-type': 'application/json',
|
|
111
209
|
accept: 'application/json',
|
|
112
210
|
};
|
|
113
|
-
const
|
|
114
|
-
const timeoutId = setTimeout(() => controller.abort(), core_2.REQUEST_TIMEOUT_MS);
|
|
211
|
+
const { signal: requestSignal, timeoutMs: effectiveTimeoutMs, timedOut, cleanup, } = buildRequestAbortSignal(options);
|
|
115
212
|
const startTime = performance.now();
|
|
116
213
|
try {
|
|
117
|
-
const
|
|
214
|
+
const safeUrl = buildAugustUrl('public', relativeUrl);
|
|
215
|
+
const res = await fetch(safeUrl, {
|
|
118
216
|
headers: {
|
|
119
217
|
...defaultHeaders,
|
|
120
218
|
...options?.headers,
|
|
121
219
|
},
|
|
122
220
|
method: options?.method ?? 'GET',
|
|
123
221
|
body: JSON.stringify(options?.data),
|
|
124
|
-
signal:
|
|
222
|
+
signal: requestSignal,
|
|
125
223
|
});
|
|
126
|
-
|
|
224
|
+
cleanup();
|
|
127
225
|
(0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, res.status, 'public');
|
|
128
|
-
const correlationId = res.headers
|
|
226
|
+
const correlationId = readResponseHeader(res.headers, 'x-correlation-id');
|
|
129
227
|
const logger = logger_1.Logger.getLogger();
|
|
130
228
|
if (!res.ok || res.status !== 200) {
|
|
131
229
|
if (correlationId && logger) {
|
|
132
230
|
logger.setTag('correlation_id', correlationId);
|
|
133
231
|
}
|
|
134
|
-
const error =
|
|
232
|
+
const error = errorFromResponseStatus(res.status, `Request failed: ${res.status}`, { correlationId });
|
|
135
233
|
logger?.captureException(error, { correlationId, status: res.status });
|
|
136
234
|
throw error;
|
|
137
235
|
}
|
|
138
236
|
return res;
|
|
139
237
|
}
|
|
140
238
|
catch (error) {
|
|
141
|
-
|
|
239
|
+
cleanup();
|
|
142
240
|
(0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, 0, 'public');
|
|
143
|
-
|
|
144
|
-
|
|
241
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
242
|
+
if (err.name === 'AbortError') {
|
|
243
|
+
if (!timedOut()) {
|
|
244
|
+
throw err;
|
|
245
|
+
}
|
|
246
|
+
const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
|
|
145
247
|
logger_1.Logger.log.error('fetchAugustPublic', timeoutError, { relativeUrl });
|
|
146
248
|
throw timeoutError;
|
|
147
249
|
}
|
|
148
|
-
throw
|
|
250
|
+
throw err;
|
|
149
251
|
}
|
|
150
252
|
}
|
|
151
253
|
async function fetchAugustWithBearer(bearerToken, relativeUrl, options) {
|
|
@@ -154,43 +256,47 @@ async function fetchAugustWithBearer(bearerToken, relativeUrl, options) {
|
|
|
154
256
|
'content-type': 'application/json',
|
|
155
257
|
accept: 'application/json',
|
|
156
258
|
};
|
|
157
|
-
const
|
|
158
|
-
const timeoutId = setTimeout(() => controller.abort(), core_2.REQUEST_TIMEOUT_MS);
|
|
259
|
+
const { signal: requestSignal, timeoutMs: effectiveTimeoutMs, timedOut, cleanup, } = buildRequestAbortSignal(options);
|
|
159
260
|
const startTime = performance.now();
|
|
160
261
|
const server = options?.server ?? 'production';
|
|
161
262
|
try {
|
|
162
|
-
const
|
|
263
|
+
const safeUrl = buildAugustUrl(server, relativeUrl);
|
|
264
|
+
const res = await fetch(safeUrl, {
|
|
163
265
|
headers: {
|
|
164
266
|
...defaultHeaders,
|
|
165
|
-
...options
|
|
267
|
+
...options?.headers,
|
|
166
268
|
},
|
|
167
|
-
method: options
|
|
168
|
-
body: JSON.stringify(options
|
|
169
|
-
signal:
|
|
269
|
+
method: options?.method ?? 'GET',
|
|
270
|
+
body: JSON.stringify(options?.data),
|
|
271
|
+
signal: requestSignal,
|
|
170
272
|
});
|
|
171
|
-
|
|
273
|
+
cleanup();
|
|
172
274
|
(0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, res.status, server);
|
|
173
|
-
const correlationId = res.headers
|
|
275
|
+
const correlationId = readResponseHeader(res.headers, 'x-correlation-id');
|
|
174
276
|
const logger = logger_1.Logger.getLogger();
|
|
175
277
|
if (!res.ok || res.status !== 200) {
|
|
176
278
|
if (correlationId && logger) {
|
|
177
279
|
logger.setTag('correlation_id', correlationId);
|
|
178
280
|
}
|
|
179
|
-
const error =
|
|
281
|
+
const error = errorFromResponseStatus(res.status, `Request failed: ${res.status}`, { correlationId });
|
|
180
282
|
logger?.captureException(error, { correlationId, status: res.status });
|
|
181
283
|
throw error;
|
|
182
284
|
}
|
|
183
285
|
return res;
|
|
184
286
|
}
|
|
185
287
|
catch (error) {
|
|
186
|
-
|
|
288
|
+
cleanup();
|
|
187
289
|
(0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, 0, server);
|
|
188
|
-
|
|
189
|
-
|
|
290
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
291
|
+
if (err.name === 'AbortError') {
|
|
292
|
+
if (!timedOut()) {
|
|
293
|
+
throw err;
|
|
294
|
+
}
|
|
295
|
+
const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
|
|
190
296
|
logger_1.Logger.log.error('fetchAugustWithBearer', timeoutError, { relativeUrl });
|
|
191
297
|
throw timeoutError;
|
|
192
298
|
}
|
|
193
|
-
throw
|
|
299
|
+
throw err;
|
|
194
300
|
}
|
|
195
301
|
}
|
|
196
302
|
function isRetryableError(error) {
|
|
@@ -273,10 +379,11 @@ async function fetchTokenizedVaults(pool, headers, loadSubaccounts, loadSnapshot
|
|
|
273
379
|
keyParts.push('no-snapshots');
|
|
274
380
|
const key = keyParts.join('-');
|
|
275
381
|
let tokenizedVaults;
|
|
276
|
-
|
|
277
|
-
|
|
382
|
+
const cachedResponse = await (0, exports.getSafeCache)(key);
|
|
383
|
+
if (cachedResponse) {
|
|
384
|
+
tokenizedVaults = cachedResponse;
|
|
278
385
|
}
|
|
279
|
-
|
|
386
|
+
if (!tokenizedVaults) {
|
|
280
387
|
let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.list;
|
|
281
388
|
const params = new URLSearchParams();
|
|
282
389
|
if (loadSubaccounts === false) {
|
|
@@ -294,7 +401,8 @@ async function fetchTokenizedVaults(pool, headers, loadSubaccounts, loadSnapshot
|
|
|
294
401
|
});
|
|
295
402
|
tokenizedVaults =
|
|
296
403
|
(await tokenizedVaultsResponse.json());
|
|
297
|
-
|
|
404
|
+
const ttl = 1000 * 60 * 15;
|
|
405
|
+
exports.CACHE.set(key, tokenizedVaults, { ttl });
|
|
298
406
|
}
|
|
299
407
|
if (pool &&
|
|
300
408
|
((0, ethers_1.isAddress)(pool) ||
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ethers, Interface, InterfaceAbi } from 'ethers';
|
|
1
|
+
import { ethers, Interface, InterfaceAbi, JsonRpcProvider } from 'ethers';
|
|
2
2
|
import type { Abi } from 'abitype';
|
|
3
3
|
import type { TypedContract } from '../../types/typed-contract';
|
|
4
4
|
import { IAddress, IChainId, IContractRunner, IExplorerType, IInfuraOptions } from '../../types';
|
|
@@ -11,8 +11,8 @@ export declare function createContract<const TAbi extends Abi>({ provider, addre
|
|
|
11
11
|
provider: IContractRunner;
|
|
12
12
|
abi: TAbi;
|
|
13
13
|
}): TypedContract<TAbi> | undefined;
|
|
14
|
-
export declare const createProvider: (rpcUrl: string) =>
|
|
15
|
-
export declare const getInfuraProvider: (infura: IInfuraOptions) =>
|
|
14
|
+
export declare const createProvider: (rpcUrl: string, chainId?: number) => JsonRpcProvider;
|
|
15
|
+
export declare const getInfuraProvider: (infura: IInfuraOptions) => JsonRpcProvider;
|
|
16
16
|
export declare const explorerLink: (hex: IAddress, chain: IChainId, type: IExplorerType) => string;
|
|
17
17
|
export declare const getDecimals: (provider: IContractRunner, address: IAddress, isVault?: boolean) => Promise<any>;
|
|
18
18
|
export declare const getReceiptTokenAddress: (provider: IContractRunner, address: IAddress) => Promise<any>;
|
package/lib/core/helpers/web3.js
CHANGED
|
@@ -48,6 +48,8 @@ const determineBlockSkipInternal = (chain) => {
|
|
|
48
48
|
return 8000;
|
|
49
49
|
case 143:
|
|
50
50
|
return 1000;
|
|
51
|
+
case 999:
|
|
52
|
+
return 1000;
|
|
51
53
|
default:
|
|
52
54
|
return 50000;
|
|
53
55
|
}
|
|
@@ -78,11 +80,26 @@ function createContract({ provider, address, abi, }) {
|
|
|
78
80
|
}
|
|
79
81
|
return contract;
|
|
80
82
|
}
|
|
81
|
-
const createProvider = (rpcUrl) => {
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const createProvider = (rpcUrl, chainId) => {
|
|
84
|
+
if (typeof rpcUrl !== 'string' || rpcUrl.trim().length === 0) {
|
|
85
|
+
const forChain = chainId ? ` for chain ${chainId}` : '';
|
|
86
|
+
throw new Error(`createProvider: no RPC URL provided${forChain}. ` +
|
|
87
|
+
'Pass an RPC URL when constructing AugustSDK ' +
|
|
88
|
+
'(`new AugustSDK({ providers: { [chainId]: url } })`), ' +
|
|
89
|
+
`or set the AUGUST_RPC_${chainId ?? '<chainId>'} environment variable.`);
|
|
90
|
+
}
|
|
91
|
+
const cacheKey = chainId ? `${rpcUrl}|${chainId}` : rpcUrl;
|
|
92
|
+
if (__1.CACHE.has(cacheKey))
|
|
93
|
+
return __1.CACHE.get(cacheKey);
|
|
94
|
+
const provider = chainId
|
|
95
|
+
? new ethers_1.JsonRpcProvider(rpcUrl, ethers_1.Network.from(chainId), {
|
|
96
|
+
staticNetwork: ethers_1.Network.from(chainId),
|
|
97
|
+
batchMaxCount: 10,
|
|
98
|
+
})
|
|
99
|
+
: new ethers_1.JsonRpcProvider(rpcUrl, undefined, {
|
|
100
|
+
batchMaxCount: 10,
|
|
101
|
+
});
|
|
102
|
+
__1.CACHE.set(cacheKey, provider);
|
|
86
103
|
return provider;
|
|
87
104
|
};
|
|
88
105
|
exports.createProvider = createProvider;
|
|
@@ -110,7 +127,8 @@ const getInfuraProvider = (infura) => {
|
|
|
110
127
|
break;
|
|
111
128
|
}
|
|
112
129
|
}
|
|
113
|
-
|
|
130
|
+
const url = `${baseUrl}.infura.io/v3/${infura.apiKey}`;
|
|
131
|
+
return (0, exports.createProvider)(url, infura.chainId);
|
|
114
132
|
};
|
|
115
133
|
exports.getInfuraProvider = getInfuraProvider;
|
|
116
134
|
const explorerLink = (hex, chain, type) => {
|
|
@@ -119,6 +137,24 @@ const explorerLink = (hex, chain, type) => {
|
|
|
119
137
|
return `${__1.NETWORKS[chain].explorer}/${type}/${hex}`;
|
|
120
138
|
};
|
|
121
139
|
exports.explorerLink = explorerLink;
|
|
140
|
+
function providerScope(provider) {
|
|
141
|
+
let chainId;
|
|
142
|
+
try {
|
|
143
|
+
const net = provider
|
|
144
|
+
._network;
|
|
145
|
+
chainId = net?.chainId;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
chainId = undefined;
|
|
149
|
+
}
|
|
150
|
+
if (chainId !== undefined && chainId !== null) {
|
|
151
|
+
return `chain:${String(chainId)}`;
|
|
152
|
+
}
|
|
153
|
+
const conn = provider._getConnection?.();
|
|
154
|
+
if (conn?.url)
|
|
155
|
+
return `url:${conn.url}`;
|
|
156
|
+
return 'unknown';
|
|
157
|
+
}
|
|
122
158
|
const getDecimals = async (provider, address, isVault = true) => {
|
|
123
159
|
if (address === ethers_1.ZeroAddress) {
|
|
124
160
|
__1.Logger.log.info('getDecimals', 'address is zero address');
|
|
@@ -128,7 +164,7 @@ const getDecimals = async (provider, address, isVault = true) => {
|
|
|
128
164
|
return constants_1.fallbackDecimals;
|
|
129
165
|
if (!(address && provider))
|
|
130
166
|
return;
|
|
131
|
-
const key = `decimals-${address}`;
|
|
167
|
+
const key = `decimals-${providerScope(provider)}-${address}`;
|
|
132
168
|
try {
|
|
133
169
|
if (__1.CACHE.get(key))
|
|
134
170
|
return __1.CACHE.get(key);
|
|
@@ -159,7 +195,7 @@ exports.getDecimals = getDecimals;
|
|
|
159
195
|
const getReceiptTokenAddress = async (provider, address) => {
|
|
160
196
|
if (!(address && provider))
|
|
161
197
|
return;
|
|
162
|
-
const key = `receipt-token-${address}`;
|
|
198
|
+
const key = `receipt-token-${providerScope(provider)}-${address}`;
|
|
163
199
|
try {
|
|
164
200
|
if (__1.CACHE.get(key))
|
|
165
201
|
return __1.CACHE.get(key);
|
|
@@ -180,7 +216,7 @@ const getSymbol = async (provider, address, isVault = true) => {
|
|
|
180
216
|
}
|
|
181
217
|
if (!(address && provider))
|
|
182
218
|
return;
|
|
183
|
-
const key = `symbol-${address}`;
|
|
219
|
+
const key = `symbol-${providerScope(provider)}-${address}`;
|
|
184
220
|
try {
|
|
185
221
|
if (__1.CACHE.get(key))
|
|
186
222
|
return __1.CACHE.get(key);
|
package/lib/core/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export * from './base.class';
|
|
|
3
3
|
export * from './auth';
|
|
4
4
|
export * from './logger';
|
|
5
5
|
export * from './analytics';
|
|
6
|
+
export * from './version-check';
|
|
7
|
+
export * from './errors';
|
|
6
8
|
export * from './constants/adapters';
|
|
7
9
|
export * from './constants/core';
|
|
8
10
|
export * from './constants/web3';
|
package/lib/core/index.js
CHANGED
|
@@ -19,6 +19,8 @@ __exportStar(require("./base.class"), exports);
|
|
|
19
19
|
__exportStar(require("./auth"), exports);
|
|
20
20
|
__exportStar(require("./logger"), exports);
|
|
21
21
|
__exportStar(require("./analytics"), exports);
|
|
22
|
+
__exportStar(require("./version-check"), exports);
|
|
23
|
+
__exportStar(require("./errors"), exports);
|
|
22
24
|
__exportStar(require("./constants/adapters"), exports);
|
|
23
25
|
__exportStar(require("./constants/core"), exports);
|
|
24
26
|
__exportStar(require("./constants/web3"), exports);
|
|
@@ -2,13 +2,23 @@ export type SDKLogger = {
|
|
|
2
2
|
setTag: (key: string, value: string) => void;
|
|
3
3
|
captureException: (err: unknown, context?: Record<string, any>) => void;
|
|
4
4
|
};
|
|
5
|
+
export interface ILogger {
|
|
6
|
+
debug?: (tag: string, context?: Record<string, unknown>) => void;
|
|
7
|
+
info?: (tag: string, context?: Record<string, unknown>) => void;
|
|
8
|
+
warn?: (tag: string, context?: Record<string, unknown>) => void;
|
|
9
|
+
error: (tag: string, error: unknown, context?: Record<string, unknown>) => void;
|
|
10
|
+
}
|
|
5
11
|
declare function setLogger(customLogger: SDKLogger): void;
|
|
12
|
+
declare function setStructuredLogger(custom: ILogger | null): void;
|
|
6
13
|
declare function getLogger(): SDKLogger | null;
|
|
14
|
+
declare function getStructuredLogger(): ILogger | null;
|
|
7
15
|
declare function setDevMode(devMode: boolean): void;
|
|
8
16
|
declare function isDevMode(): boolean;
|
|
9
17
|
declare const Logger: {
|
|
10
18
|
setLogger: typeof setLogger;
|
|
19
|
+
setStructuredLogger: typeof setStructuredLogger;
|
|
11
20
|
getLogger: typeof getLogger;
|
|
21
|
+
getStructuredLogger: typeof getStructuredLogger;
|
|
12
22
|
setDevMode: typeof setDevMode;
|
|
13
23
|
isDevMode: typeof isDevMode;
|
|
14
24
|
log: {
|
package/lib/core/logger/index.js
CHANGED
|
@@ -34,14 +34,22 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Logger = exports.Slack = void 0;
|
|
37
|
+
const sanitize_1 = require("../analytics/sanitize");
|
|
37
38
|
let logger = null;
|
|
39
|
+
let structuredLogger = null;
|
|
38
40
|
let isDev = false;
|
|
39
41
|
function setLogger(customLogger) {
|
|
40
42
|
logger = customLogger;
|
|
41
43
|
}
|
|
44
|
+
function setStructuredLogger(custom) {
|
|
45
|
+
structuredLogger = custom;
|
|
46
|
+
}
|
|
42
47
|
function getLogger() {
|
|
43
48
|
return logger;
|
|
44
49
|
}
|
|
50
|
+
function getStructuredLogger() {
|
|
51
|
+
return structuredLogger;
|
|
52
|
+
}
|
|
45
53
|
function setDevMode(devMode) {
|
|
46
54
|
isDev = devMode;
|
|
47
55
|
}
|
|
@@ -50,26 +58,51 @@ function isDevMode() {
|
|
|
50
58
|
}
|
|
51
59
|
const log = {
|
|
52
60
|
info: (tag, ...args) => {
|
|
61
|
+
const safeArgs = args.map((a) => (0, sanitize_1.sanitizeForLogging)(a));
|
|
53
62
|
if (isDev) {
|
|
54
|
-
console.log(`[${tag}]`, ...
|
|
63
|
+
console.log(`[${tag}]`, ...safeArgs);
|
|
55
64
|
}
|
|
65
|
+
structuredLogger?.info?.(tag, structuredContext(safeArgs));
|
|
56
66
|
},
|
|
57
67
|
warn: (tag, ...args) => {
|
|
68
|
+
const safeArgs = args.map((a) => (0, sanitize_1.sanitizeForLogging)(a));
|
|
58
69
|
if (isDev) {
|
|
59
|
-
console.warn(`[${tag}]`, ...
|
|
70
|
+
console.warn(`[${tag}]`, ...safeArgs);
|
|
60
71
|
}
|
|
61
72
|
logger?.setTag('warning', tag);
|
|
73
|
+
structuredLogger?.warn?.(tag, structuredContext(safeArgs));
|
|
62
74
|
},
|
|
63
75
|
error: (tag, error, context) => {
|
|
76
|
+
const safeError = (0, sanitize_1.sanitizeError)(error);
|
|
77
|
+
const safeContext = context
|
|
78
|
+
? (0, sanitize_1.sanitizeForLogging)(context)
|
|
79
|
+
: undefined;
|
|
64
80
|
if (isDev) {
|
|
65
|
-
console.error(`[${tag}]`,
|
|
81
|
+
console.error(`[${tag}]`, safeError);
|
|
66
82
|
}
|
|
67
|
-
logger?.captureException(
|
|
83
|
+
logger?.captureException(safeError, { tag, ...(safeContext ?? {}) });
|
|
84
|
+
structuredLogger?.error(tag, safeError, safeContext);
|
|
68
85
|
},
|
|
69
86
|
};
|
|
87
|
+
function structuredContext(args) {
|
|
88
|
+
if (args.length === 0)
|
|
89
|
+
return undefined;
|
|
90
|
+
const [first, ...rest] = args;
|
|
91
|
+
if (first &&
|
|
92
|
+
typeof first === 'object' &&
|
|
93
|
+
!Array.isArray(first) &&
|
|
94
|
+
!(first instanceof Error)) {
|
|
95
|
+
return rest.length === 0
|
|
96
|
+
? first
|
|
97
|
+
: { ...first, extras: rest };
|
|
98
|
+
}
|
|
99
|
+
return { args };
|
|
100
|
+
}
|
|
70
101
|
const Logger = {
|
|
71
102
|
setLogger,
|
|
103
|
+
setStructuredLogger,
|
|
72
104
|
getLogger,
|
|
105
|
+
getStructuredLogger,
|
|
73
106
|
setDevMode,
|
|
74
107
|
isDevMode,
|
|
75
108
|
log,
|
package/lib/core/logger/slack.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SLACK = exports.DEFAULT_SLACK_WEBHOOK_URL = void 0;
|
|
4
4
|
const core_1 = require("../helpers/core");
|
|
5
5
|
const web3_1 = require("../helpers/web3");
|
|
6
|
+
const sanitize_1 = require("../analytics/sanitize");
|
|
6
7
|
exports.DEFAULT_SLACK_WEBHOOK_URL = 'T04CM84GAV6/B0A2DS3ST8C/FLtOA3Jna3FN7UO4DoGxHfhG';
|
|
7
8
|
function error(options) {
|
|
8
9
|
const { title, error, poolAddress, chainId, slackWebookUrl, address } = options;
|
|
@@ -31,18 +32,21 @@ function error(options) {
|
|
|
31
32
|
}
|
|
32
33
|
(async () => {
|
|
33
34
|
const webhookUrl = `https://hooks.slack.com/services/${slackWebookUrl}`;
|
|
35
|
+
const safeError = (0, sanitize_1.sanitizeString)(String(error));
|
|
36
|
+
const safeTitle = (0, sanitize_1.sanitizeString)(String(title));
|
|
34
37
|
const data = {
|
|
35
|
-
text: `*Error: ${
|
|
38
|
+
text: `*Error: ${safeTitle}*\n${new Date().toUTCString()}\n\nPool: [${(0, core_1.truncate)(poolAddress)}](${(0, web3_1.explorerLink)(poolAddress, chainId, 'address')})\n\n\nError: ${safeError}`,
|
|
36
39
|
};
|
|
37
40
|
const res = await fetch(webhookUrl, {
|
|
38
41
|
method: 'POST',
|
|
39
42
|
body: JSON.stringify(data),
|
|
43
|
+
signal: AbortSignal.timeout(5000),
|
|
40
44
|
});
|
|
41
45
|
if (res?.status === 200)
|
|
42
46
|
console.log('#Slack.error: successfully sent');
|
|
43
47
|
else
|
|
44
48
|
console.error('#Slack.error:', res.status, res.statusText);
|
|
45
|
-
})().catch((e) => console.error('#Slack.error:', e));
|
|
49
|
+
})().catch((e) => console.error('#Slack.error:', (0, sanitize_1.sanitizeString)(String(e?.message ?? e))));
|
|
46
50
|
}
|
|
47
51
|
exports.SLACK = {
|
|
48
52
|
error,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
2
|
+
export interface IVersionCheckConfig {
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function runVersionCheck(config?: IVersionCheckConfig): void;
|
|
6
|
+
export declare function _resetVersionCheckForTests(): void;
|