@augustdigital/sdk 4.27.4-alpha.0 → 5.1.1
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/adapters/solana/getters.js +9 -2
- package/lib/adapters/solana/idl/vault-idl.js +14 -0
- package/lib/adapters/solana/index.d.ts +11 -0
- package/lib/adapters/solana/index.js +8 -0
- package/lib/adapters/solana/types.d.ts +4 -1
- package/lib/adapters/solana/utils.d.ts +8 -0
- package/lib/adapters/solana/utils.js +24 -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 +43 -11
- 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 +25 -6
- package/lib/modules/vaults/getters.d.ts +5 -1
- package/lib/modules/vaults/getters.js +40 -26
- package/lib/modules/vaults/main.d.ts +7 -1
- package/lib/modules/vaults/main.js +32 -1
- package/lib/modules/vaults/types.d.ts +4 -0
- package/lib/polyfills.d.ts +1 -0
- package/lib/polyfills.js +10 -0
- package/package.json +27 -18
- 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/cache.d.ts +0 -25
- package/lib/core/cache.js +0 -53
- package/lib/core/cache.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/callDataDecoder.d.ts +0 -14
- package/lib/modules/vaults/utils/callDataDecoder.js +0 -138
- package/lib/modules/vaults/utils/callDataDecoder.js.map +0 -1
- package/lib/modules/vaults/utils/date-utils.js.map +0 -1
- package/lib/modules/vaults/utils/dateUtils.d.ts +0 -11
- package/lib/modules/vaults/utils/dateUtils.js +0 -39
- package/lib/modules/vaults/utils/dateUtils.js.map +0 -1
- package/lib/modules/vaults/utils/index.d.ts +0 -2
- package/lib/modules/vaults/utils/index.js +0 -19
- package/lib/modules/vaults/utils/index.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
|
@@ -80,13 +80,26 @@ function createContract({ provider, address, abi, }) {
|
|
|
80
80
|
}
|
|
81
81
|
return contract;
|
|
82
82
|
}
|
|
83
|
-
const createProvider = (rpcUrl) => {
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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);
|
|
90
103
|
return provider;
|
|
91
104
|
};
|
|
92
105
|
exports.createProvider = createProvider;
|
|
@@ -114,7 +127,8 @@ const getInfuraProvider = (infura) => {
|
|
|
114
127
|
break;
|
|
115
128
|
}
|
|
116
129
|
}
|
|
117
|
-
|
|
130
|
+
const url = `${baseUrl}.infura.io/v3/${infura.apiKey}`;
|
|
131
|
+
return (0, exports.createProvider)(url, infura.chainId);
|
|
118
132
|
};
|
|
119
133
|
exports.getInfuraProvider = getInfuraProvider;
|
|
120
134
|
const explorerLink = (hex, chain, type) => {
|
|
@@ -123,6 +137,24 @@ const explorerLink = (hex, chain, type) => {
|
|
|
123
137
|
return `${__1.NETWORKS[chain].explorer}/${type}/${hex}`;
|
|
124
138
|
};
|
|
125
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
|
+
}
|
|
126
158
|
const getDecimals = async (provider, address, isVault = true) => {
|
|
127
159
|
if (address === ethers_1.ZeroAddress) {
|
|
128
160
|
__1.Logger.log.info('getDecimals', 'address is zero address');
|
|
@@ -132,7 +164,7 @@ const getDecimals = async (provider, address, isVault = true) => {
|
|
|
132
164
|
return constants_1.fallbackDecimals;
|
|
133
165
|
if (!(address && provider))
|
|
134
166
|
return;
|
|
135
|
-
const key = `decimals-${address}`;
|
|
167
|
+
const key = `decimals-${providerScope(provider)}-${address}`;
|
|
136
168
|
try {
|
|
137
169
|
if (__1.CACHE.get(key))
|
|
138
170
|
return __1.CACHE.get(key);
|
|
@@ -163,7 +195,7 @@ exports.getDecimals = getDecimals;
|
|
|
163
195
|
const getReceiptTokenAddress = async (provider, address) => {
|
|
164
196
|
if (!(address && provider))
|
|
165
197
|
return;
|
|
166
|
-
const key = `receipt-token-${address}`;
|
|
198
|
+
const key = `receipt-token-${providerScope(provider)}-${address}`;
|
|
167
199
|
try {
|
|
168
200
|
if (__1.CACHE.get(key))
|
|
169
201
|
return __1.CACHE.get(key);
|
|
@@ -184,7 +216,7 @@ const getSymbol = async (provider, address, isVault = true) => {
|
|
|
184
216
|
}
|
|
185
217
|
if (!(address && provider))
|
|
186
218
|
return;
|
|
187
|
-
const key = `symbol-${address}`;
|
|
219
|
+
const key = `symbol-${providerScope(provider)}-${address}`;
|
|
188
220
|
try {
|
|
189
221
|
if (__1.CACHE.get(key))
|
|
190
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;
|