upshift-sdk 8.20.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.
Files changed (316) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +349 -0
  3. package/lib/abis/AddressResolver.d.ts +28 -0
  4. package/lib/abis/AddressResolver.js +23 -0
  5. package/lib/abis/ChainlinkV3.d.ts +87 -0
  6. package/lib/abis/ChainlinkV3.js +117 -0
  7. package/lib/abis/ERC20.d.ts +168 -0
  8. package/lib/abis/ERC20.js +226 -0
  9. package/lib/abis/ERC20_Bytes32.d.ts +139 -0
  10. package/lib/abis/ERC20_Bytes32.js +196 -0
  11. package/lib/abis/ERC4626.d.ts +364 -0
  12. package/lib/abis/ERC4626.js +507 -0
  13. package/lib/abis/ERC721.d.ts +231 -0
  14. package/lib/abis/ERC721.js +321 -0
  15. package/lib/abis/FeeOracle.d.ts +120 -0
  16. package/lib/abis/FeeOracle.js +162 -0
  17. package/lib/abis/LendingPool.d.ts +1393 -0
  18. package/lib/abis/LendingPool.js +1807 -0
  19. package/lib/abis/LendingPoolV2.d.ts +1413 -0
  20. package/lib/abis/LendingPoolV2.js +1833 -0
  21. package/lib/abis/LendingPoolV3.d.ts +1677 -0
  22. package/lib/abis/LendingPoolV3.js +1160 -0
  23. package/lib/abis/Loan.d.ts +837 -0
  24. package/lib/abis/Loan.js +1080 -0
  25. package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
  26. package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
  27. package/lib/abis/Multicall3.d.ts +30 -0
  28. package/lib/abis/Multicall3.js +97 -0
  29. package/lib/abis/OFT.d.ts +116 -0
  30. package/lib/abis/OFT.js +85 -0
  31. package/lib/abis/PoolAdapter.d.ts +36 -0
  32. package/lib/abis/PoolAdapter.js +51 -0
  33. package/lib/abis/RewardDistributor.d.ts +267 -0
  34. package/lib/abis/RewardDistributor.js +352 -0
  35. package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
  36. package/lib/abis/RwaRedeemSubaccount.js +548 -0
  37. package/lib/abis/SmartAccount.d.ts +17 -0
  38. package/lib/abis/SmartAccount.js +19 -0
  39. package/lib/abis/SwapRouter.d.ts +1043 -0
  40. package/lib/abis/SwapRouter.js +740 -0
  41. package/lib/abis/TextResolver.d.ts +16 -0
  42. package/lib/abis/TextResolver.js +16 -0
  43. package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
  44. package/lib/abis/TokenizedVaultV2.js +1041 -0
  45. package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
  46. package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
  47. package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
  48. package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
  49. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
  50. package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
  51. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
  52. package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
  53. package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
  54. package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
  55. package/lib/abis/UniversalResolverResolve.d.ts +69 -0
  56. package/lib/abis/UniversalResolverResolve.js +35 -0
  57. package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
  58. package/lib/abis/UniversalSignatureValidator.js +30 -0
  59. package/lib/abis/WrapperAdapter.d.ts +71 -0
  60. package/lib/abis/WrapperAdapter.js +77 -0
  61. package/lib/abis/index.d.ts +34 -0
  62. package/lib/abis/index.js +51 -0
  63. package/lib/adapters/evm/getters.d.ts +19 -0
  64. package/lib/adapters/evm/getters.js +209 -0
  65. package/lib/adapters/evm/index.d.ts +353 -0
  66. package/lib/adapters/evm/index.js +434 -0
  67. package/lib/adapters/evm/utils.d.ts +8 -0
  68. package/lib/adapters/evm/utils.js +51 -0
  69. package/lib/adapters/solana/constants.d.ts +33 -0
  70. package/lib/adapters/solana/constants.js +52 -0
  71. package/lib/adapters/solana/getters.d.ts +11 -0
  72. package/lib/adapters/solana/getters.js +165 -0
  73. package/lib/adapters/solana/idl/vault-idl.d.ts +272 -0
  74. package/lib/adapters/solana/idl/vault-idl.js +1084 -0
  75. package/lib/adapters/solana/index.d.ts +233 -0
  76. package/lib/adapters/solana/index.js +291 -0
  77. package/lib/adapters/solana/types.d.ts +67 -0
  78. package/lib/adapters/solana/types.js +3 -0
  79. package/lib/adapters/solana/utils.d.ts +141 -0
  80. package/lib/adapters/solana/utils.js +595 -0
  81. package/lib/adapters/solana/vault.actions.d.ts +57 -0
  82. package/lib/adapters/solana/vault.actions.js +379 -0
  83. package/lib/adapters/stellar/actions.d.ts +28 -0
  84. package/lib/adapters/stellar/actions.js +77 -0
  85. package/lib/adapters/stellar/constants.d.ts +43 -0
  86. package/lib/adapters/stellar/constants.js +53 -0
  87. package/lib/adapters/stellar/getters.d.ts +68 -0
  88. package/lib/adapters/stellar/getters.js +290 -0
  89. package/lib/adapters/stellar/index.d.ts +114 -0
  90. package/lib/adapters/stellar/index.js +175 -0
  91. package/lib/adapters/stellar/soroban.d.ts +123 -0
  92. package/lib/adapters/stellar/soroban.js +613 -0
  93. package/lib/adapters/stellar/submit.d.ts +34 -0
  94. package/lib/adapters/stellar/submit.js +149 -0
  95. package/lib/adapters/stellar/types.d.ts +58 -0
  96. package/lib/adapters/stellar/types.js +6 -0
  97. package/lib/adapters/stellar/utils.d.ts +24 -0
  98. package/lib/adapters/stellar/utils.js +34 -0
  99. package/lib/adapters/sui/constants.d.ts +14 -0
  100. package/lib/adapters/sui/constants.js +29 -0
  101. package/lib/adapters/sui/getters.d.ts +9 -0
  102. package/lib/adapters/sui/getters.js +60 -0
  103. package/lib/adapters/sui/index.d.ts +45 -0
  104. package/lib/adapters/sui/index.js +101 -0
  105. package/lib/adapters/sui/transformer.d.ts +10 -0
  106. package/lib/adapters/sui/transformer.js +107 -0
  107. package/lib/adapters/sui/types.d.ts +66 -0
  108. package/lib/adapters/sui/types.js +3 -0
  109. package/lib/adapters/sui/utils.d.ts +10 -0
  110. package/lib/adapters/sui/utils.js +29 -0
  111. package/lib/core/analytics/chain-name.d.ts +9 -0
  112. package/lib/core/analytics/chain-name.js +34 -0
  113. package/lib/core/analytics/constants.d.ts +5 -0
  114. package/lib/core/analytics/constants.js +9 -0
  115. package/lib/core/analytics/env.d.ts +29 -0
  116. package/lib/core/analytics/env.js +59 -0
  117. package/lib/core/analytics/index.d.ts +36 -0
  118. package/lib/core/analytics/index.js +79 -0
  119. package/lib/core/analytics/instrumentation.d.ts +29 -0
  120. package/lib/core/analytics/instrumentation.js +277 -0
  121. package/lib/core/analytics/method-taxonomy.d.ts +19 -0
  122. package/lib/core/analytics/method-taxonomy.js +128 -0
  123. package/lib/core/analytics/metrics.d.ts +33 -0
  124. package/lib/core/analytics/metrics.js +116 -0
  125. package/lib/core/analytics/sanitize.d.ts +44 -0
  126. package/lib/core/analytics/sanitize.js +260 -0
  127. package/lib/core/analytics/sentry-runtime.d.ts +15 -0
  128. package/lib/core/analytics/sentry-runtime.js +97 -0
  129. package/lib/core/analytics/sentry.d.ts +67 -0
  130. package/lib/core/analytics/sentry.js +613 -0
  131. package/lib/core/analytics/types.d.ts +48 -0
  132. package/lib/core/analytics/types.js +3 -0
  133. package/lib/core/analytics/user-identity.d.ts +41 -0
  134. package/lib/core/analytics/user-identity.js +141 -0
  135. package/lib/core/analytics/version.d.ts +6 -0
  136. package/lib/core/analytics/version.js +10 -0
  137. package/lib/core/attribution.d.ts +111 -0
  138. package/lib/core/attribution.js +142 -0
  139. package/lib/core/auth/index.d.ts +1 -0
  140. package/lib/core/auth/index.js +18 -0
  141. package/lib/core/auth/verify.d.ts +2 -0
  142. package/lib/core/auth/verify.js +31 -0
  143. package/lib/core/base.class.d.ts +152 -0
  144. package/lib/core/base.class.js +172 -0
  145. package/lib/core/cache.d.ts +9 -0
  146. package/lib/core/cache.js +31 -0
  147. package/lib/core/constants/adapters.d.ts +103 -0
  148. package/lib/core/constants/adapters.js +180 -0
  149. package/lib/core/constants/core.d.ts +133 -0
  150. package/lib/core/constants/core.js +209 -0
  151. package/lib/core/constants/swap-router.d.ts +150 -0
  152. package/lib/core/constants/swap-router.js +169 -0
  153. package/lib/core/constants/vaults.d.ts +93 -0
  154. package/lib/core/constants/vaults.js +273 -0
  155. package/lib/core/constants/web3.d.ts +91 -0
  156. package/lib/core/constants/web3.js +229 -0
  157. package/lib/core/errors/index.d.ts +114 -0
  158. package/lib/core/errors/index.js +183 -0
  159. package/lib/core/fetcher.d.ts +198 -0
  160. package/lib/core/fetcher.js +903 -0
  161. package/lib/core/helpers/adapters.d.ts +13 -0
  162. package/lib/core/helpers/adapters.js +39 -0
  163. package/lib/core/helpers/chain-address.d.ts +13 -0
  164. package/lib/core/helpers/chain-address.js +47 -0
  165. package/lib/core/helpers/chain-error.d.ts +207 -0
  166. package/lib/core/helpers/chain-error.js +682 -0
  167. package/lib/core/helpers/chain-support.d.ts +80 -0
  168. package/lib/core/helpers/chain-support.js +115 -0
  169. package/lib/core/helpers/core.d.ts +68 -0
  170. package/lib/core/helpers/core.js +285 -0
  171. package/lib/core/helpers/explorer-link.d.ts +16 -0
  172. package/lib/core/helpers/explorer-link.js +26 -0
  173. package/lib/core/helpers/multicall.d.ts +68 -0
  174. package/lib/core/helpers/multicall.js +103 -0
  175. package/lib/core/helpers/revert-decode.d.ts +248 -0
  176. package/lib/core/helpers/revert-decode.js +515 -0
  177. package/lib/core/helpers/signer.d.ts +52 -0
  178. package/lib/core/helpers/signer.js +145 -0
  179. package/lib/core/helpers/swap-router.d.ts +211 -0
  180. package/lib/core/helpers/swap-router.js +480 -0
  181. package/lib/core/helpers/vault-version.d.ts +23 -0
  182. package/lib/core/helpers/vault-version.js +75 -0
  183. package/lib/core/helpers/vaults.d.ts +89 -0
  184. package/lib/core/helpers/vaults.js +235 -0
  185. package/lib/core/helpers/web3.d.ts +353 -0
  186. package/lib/core/helpers/web3.js +992 -0
  187. package/lib/core/index.d.ts +23 -0
  188. package/lib/core/index.js +40 -0
  189. package/lib/core/logger/index.d.ts +98 -0
  190. package/lib/core/logger/index.js +144 -0
  191. package/lib/core/logger/slack.d.ts +16 -0
  192. package/lib/core/logger/slack.js +57 -0
  193. package/lib/core/vault-metadata.d.ts +12 -0
  194. package/lib/core/vault-metadata.js +42 -0
  195. package/lib/core/version-check.d.ts +58 -0
  196. package/lib/core/version-check.js +182 -0
  197. package/lib/evm/index.d.ts +2 -0
  198. package/lib/evm/index.js +19 -0
  199. package/lib/evm/methods/crossChainVault.d.ts +128 -0
  200. package/lib/evm/methods/crossChainVault.js +853 -0
  201. package/lib/evm/methods/crossChainVaultRegistry.d.ts +93 -0
  202. package/lib/evm/methods/crossChainVaultRegistry.js +240 -0
  203. package/lib/evm/methods/index.d.ts +2 -0
  204. package/lib/evm/methods/index.js +19 -0
  205. package/lib/evm/types/crossChain.d.ts +363 -0
  206. package/lib/evm/types/crossChain.js +20 -0
  207. package/lib/evm/types/index.d.ts +1 -0
  208. package/lib/evm/types/index.js +18 -0
  209. package/lib/index.d.ts +30 -0
  210. package/lib/index.js +52 -0
  211. package/lib/main.d.ts +527 -0
  212. package/lib/main.js +601 -0
  213. package/lib/modules/api/fetcher.d.ts +82 -0
  214. package/lib/modules/api/fetcher.js +150 -0
  215. package/lib/modules/api/index.d.ts +1 -0
  216. package/lib/modules/api/index.js +6 -0
  217. package/lib/modules/api/main.d.ts +313 -0
  218. package/lib/modules/api/main.js +479 -0
  219. package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
  220. package/lib/modules/sub-accounts/fetcher.js +120 -0
  221. package/lib/modules/sub-accounts/index.d.ts +2 -0
  222. package/lib/modules/sub-accounts/index.js +19 -0
  223. package/lib/modules/sub-accounts/main.d.ts +243 -0
  224. package/lib/modules/sub-accounts/main.js +205 -0
  225. package/lib/modules/sub-accounts/utils.d.ts +106 -0
  226. package/lib/modules/sub-accounts/utils.js +112 -0
  227. package/lib/modules/vaults/adapter.helpers.d.ts +64 -0
  228. package/lib/modules/vaults/adapter.helpers.js +184 -0
  229. package/lib/modules/vaults/fetcher.d.ts +147 -0
  230. package/lib/modules/vaults/fetcher.js +368 -0
  231. package/lib/modules/vaults/getters.d.ts +570 -0
  232. package/lib/modules/vaults/getters.js +3051 -0
  233. package/lib/modules/vaults/index.d.ts +20 -0
  234. package/lib/modules/vaults/index.js +44 -0
  235. package/lib/modules/vaults/main.d.ts +601 -0
  236. package/lib/modules/vaults/main.js +1623 -0
  237. package/lib/modules/vaults/prefetch.d.ts +65 -0
  238. package/lib/modules/vaults/prefetch.js +120 -0
  239. package/lib/modules/vaults/read.actions.d.ts +225 -0
  240. package/lib/modules/vaults/read.actions.js +596 -0
  241. package/lib/modules/vaults/types.d.ts +71 -0
  242. package/lib/modules/vaults/types.js +3 -0
  243. package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
  244. package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
  245. package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
  246. package/lib/modules/vaults/utils/date-utils.js +84 -0
  247. package/lib/modules/vaults/utils.d.ts +140 -0
  248. package/lib/modules/vaults/utils.js +799 -0
  249. package/lib/modules/vaults/write.actions.d.ts +529 -0
  250. package/lib/modules/vaults/write.actions.js +1749 -0
  251. package/lib/polyfills.d.ts +1 -0
  252. package/lib/polyfills.js +12 -0
  253. package/lib/sdk.d.ts +26721 -0
  254. package/lib/services/coingecko/fetcher.d.ts +15 -0
  255. package/lib/services/coingecko/fetcher.js +67 -0
  256. package/lib/services/coingecko/index.d.ts +2 -0
  257. package/lib/services/coingecko/index.js +19 -0
  258. package/lib/services/coingecko/utils.d.ts +1 -0
  259. package/lib/services/coingecko/utils.js +24 -0
  260. package/lib/services/debank/fetcher.d.ts +126 -0
  261. package/lib/services/debank/fetcher.js +47 -0
  262. package/lib/services/debank/index.d.ts +2 -0
  263. package/lib/services/debank/index.js +19 -0
  264. package/lib/services/debank/utils.d.ts +38 -0
  265. package/lib/services/debank/utils.js +297 -0
  266. package/lib/services/layerzero/deposits.d.ts +49 -0
  267. package/lib/services/layerzero/deposits.js +166 -0
  268. package/lib/services/layerzero/redeems.d.ts +20 -0
  269. package/lib/services/layerzero/redeems.js +92 -0
  270. package/lib/services/layerzero/utils.d.ts +9 -0
  271. package/lib/services/layerzero/utils.js +22 -0
  272. package/lib/services/octavfi/fetcher.d.ts +9 -0
  273. package/lib/services/octavfi/fetcher.js +103 -0
  274. package/lib/services/octavfi/index.d.ts +3 -0
  275. package/lib/services/octavfi/index.js +20 -0
  276. package/lib/services/octavfi/types.d.ts +34 -0
  277. package/lib/services/octavfi/types.js +3 -0
  278. package/lib/services/octavfi/utils.d.ts +16 -0
  279. package/lib/services/octavfi/utils.js +212 -0
  280. package/lib/services/subgraph/fetcher.d.ts +2 -0
  281. package/lib/services/subgraph/fetcher.js +61 -0
  282. package/lib/services/subgraph/index.d.ts +2 -0
  283. package/lib/services/subgraph/index.js +19 -0
  284. package/lib/services/subgraph/schema.d.ts +45 -0
  285. package/lib/services/subgraph/schema.js +75 -0
  286. package/lib/services/subgraph/vaults.d.ts +25 -0
  287. package/lib/services/subgraph/vaults.js +1106 -0
  288. package/lib/services/swap-quotes/index.d.ts +105 -0
  289. package/lib/services/swap-quotes/index.js +77 -0
  290. package/lib/services/swap-quotes/paraswap.d.ts +51 -0
  291. package/lib/services/swap-quotes/paraswap.js +138 -0
  292. package/lib/types/api.d.ts +280 -0
  293. package/lib/types/api.js +3 -0
  294. package/lib/types/index.d.ts +12 -0
  295. package/lib/types/index.js +28 -0
  296. package/lib/types/points.d.ts +28 -0
  297. package/lib/types/points.js +3 -0
  298. package/lib/types/pools.d.ts +144 -0
  299. package/lib/types/pools.js +3 -0
  300. package/lib/types/staking.d.ts +28 -0
  301. package/lib/types/staking.js +3 -0
  302. package/lib/types/sub-accounts.d.ts +140 -0
  303. package/lib/types/sub-accounts.js +3 -0
  304. package/lib/types/subgraph.d.ts +74 -0
  305. package/lib/types/subgraph.js +3 -0
  306. package/lib/types/typed-contract.d.ts +102 -0
  307. package/lib/types/typed-contract.js +3 -0
  308. package/lib/types/user.d.ts +1 -0
  309. package/lib/types/user.js +3 -0
  310. package/lib/types/vaults.d.ts +714 -0
  311. package/lib/types/vaults.js +24 -0
  312. package/lib/types/web3.d.ts +51 -0
  313. package/lib/types/web3.js +14 -0
  314. package/lib/types/webserver.d.ts +698 -0
  315. package/lib/types/webserver.js +3 -0
  316. package/package.json +78 -0
@@ -0,0 +1,903 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setSafeCache = exports.getSafeCache = exports.CACHE = void 0;
4
+ exports.setSdkRequestTimeout = setSdkRequestTimeout;
5
+ exports.getSdkRequestTimeout = getSdkRequestTimeout;
6
+ exports.setPublicApiBaseUrl = setPublicApiBaseUrl;
7
+ exports.getPublicApiBaseUrl = getPublicApiBaseUrl;
8
+ exports.fetchAugustWithKey = fetchAugustWithKey;
9
+ exports.fetchAugustPublic = fetchAugustPublic;
10
+ exports.fetchAugustWithBearer = fetchAugustWithBearer;
11
+ exports.isRetryableError = isRetryableError;
12
+ exports.withRetry = withRetry;
13
+ exports.fetchTokenizedVault = fetchTokenizedVault;
14
+ exports.fetchTokenizedVaults = fetchTokenizedVaults;
15
+ exports.fetchTokenPrice = fetchTokenPrice;
16
+ exports.fetchTokenPriceByAddress = fetchTokenPriceByAddress;
17
+ exports.fetchTokenizedVaultLoans = fetchTokenizedVaultLoans;
18
+ exports.fetchTokenizedVaultSubaccountLoans = fetchTokenizedVaultSubaccountLoans;
19
+ exports.fetchVaultHistoricalTimeseries = fetchVaultHistoricalTimeseries;
20
+ exports.promiseSettle = promiseSettle;
21
+ const core_1 = require("./helpers/core");
22
+ const ethers_1 = require("ethers");
23
+ const abis_1 = require("../abis");
24
+ const lru_cache_1 = require("lru-cache");
25
+ const chain_address_1 = require("./helpers/chain-address");
26
+ const chain_error_1 = require("./helpers/chain-error");
27
+ const fetcher_1 = require("../services/coingecko/fetcher");
28
+ const logger_1 = require("./logger");
29
+ const ethers_2 = require("ethers");
30
+ const web3_1 = require("./constants/web3");
31
+ const core_2 = require("./constants/core");
32
+ const vault_version_1 = require("./helpers/vault-version");
33
+ const analytics_1 = require("./analytics");
34
+ const sanitize_1 = require("./analytics/sanitize");
35
+ const errors_1 = require("./errors");
36
+ /** Map an HTTP status to the appropriate typed SDK error subclass. */
37
+ function errorFromResponseStatus(status, message, options) {
38
+ if (status === 401) {
39
+ return new errors_1.AugustAuthError('AUTH_UNAUTHORIZED', message, options);
40
+ }
41
+ if (status === 403) {
42
+ return new errors_1.AugustAuthError('AUTH_FORBIDDEN', message, options);
43
+ }
44
+ if (status === 429) {
45
+ return new errors_1.AugustRateLimitError(message, options);
46
+ }
47
+ return new errors_1.AugustServerError(status, message, options);
48
+ }
49
+ let SDK_REQUEST_TIMEOUT_OVERRIDE = null;
50
+ /**
51
+ * Override the default request timeout used by every August fetcher helper
52
+ * when the caller doesn't supply a per-call `timeoutMs`. Pass `null` (or
53
+ * call with no arguments) to clear the override and fall back to the
54
+ * compiled-in `REQUEST_TIMEOUT_MS`.
55
+ *
56
+ * @param ms - Positive number of milliseconds to wait before aborting, or
57
+ * `null` to clear.
58
+ */
59
+ function setSdkRequestTimeout(ms = null) {
60
+ if (ms === null) {
61
+ SDK_REQUEST_TIMEOUT_OVERRIDE = null;
62
+ return;
63
+ }
64
+ if (!Number.isFinite(ms) || ms <= 0) {
65
+ logger_1.Logger.log.warn('setSdkRequestTimeout', 'Ignoring non-positive timeout', {
66
+ ms,
67
+ });
68
+ return;
69
+ }
70
+ SDK_REQUEST_TIMEOUT_OVERRIDE = ms;
71
+ }
72
+ /**
73
+ * Read the active default request timeout — the SDK-level override if set,
74
+ * otherwise the compiled-in `REQUEST_TIMEOUT_MS`.
75
+ */
76
+ function getSdkRequestTimeout() {
77
+ return SDK_REQUEST_TIMEOUT_OVERRIDE ?? core_2.REQUEST_TIMEOUT_MS;
78
+ }
79
+ let PUBLIC_API_BASE_OVERRIDE = null;
80
+ /**
81
+ * Override the base URL used for `WEBSERVER_URL.public` requests — the
82
+ * unauthenticated vault-catalog API that `getVault` / `fetchTokenizedVault`
83
+ * (and the other `fetchAugustPublic` callers) read from. Defaults to the
84
+ * compiled-in prod base (`https://api.augustdigital.io/api/v1`); pass `null`
85
+ * (or call with no arguments) to clear.
86
+ *
87
+ * Intended for non-prod deployments that run against an ISOLATED backend
88
+ * (e.g. a staging API): set it once at construction via
89
+ * `IAugustBase.publicApiBaseUrl` so a staging-only vault resolves. Production
90
+ * leaves it unset, so behaviour is unchanged.
91
+ *
92
+ * This is a process-global override on the fetcher helpers. The SDK constructor
93
+ * calls it on EVERY instantiation (with `null` when `publicApiBaseUrl` is
94
+ * omitted), so the last `AugustSDK` instantiated is authoritative — a prod
95
+ * instance resets it to the default even after a prior staging instance set it.
96
+ * An invalid or non-http(s) URL is treated as "no override": it RESETS to the
97
+ * compiled-in default (warned) rather than retaining a prior value, so a bad env
98
+ * value can neither break fetches nor silently leave a previous instance's base
99
+ * in place.
100
+ *
101
+ * Whenever the effective base CHANGES, the shared public-response cache is
102
+ * cleared, so catalog data fetched from the previous backend is never served for
103
+ * the new one (e.g. a prod-cached vault leaking into a staging instance). Base
104
+ * changes happen at construction, when the cache is cold, so this is ~free.
105
+ *
106
+ * @param url - Absolute http(s) base URL (trailing slash is trimmed). `null`, or
107
+ * an invalid / non-http(s) value, resets to the compiled-in public base.
108
+ */
109
+ function setPublicApiBaseUrl(url = null) {
110
+ const previous = PUBLIC_API_BASE_OVERRIDE;
111
+ if (url === null) {
112
+ PUBLIC_API_BASE_OVERRIDE = null;
113
+ }
114
+ else {
115
+ let parsed = null;
116
+ try {
117
+ parsed = new URL(url);
118
+ }
119
+ catch {
120
+ parsed = null;
121
+ }
122
+ if (!parsed ||
123
+ (parsed.protocol !== 'https:' && parsed.protocol !== 'http:')) {
124
+ // Reset to the default rather than retaining a stale prior override, so
125
+ // each construction stays authoritative and a bad env value fails safe to
126
+ // prod instead of inheriting another instance's base.
127
+ logger_1.Logger.log.warn('setPublicApiBaseUrl', 'Ignoring invalid/non-http(s) URL; resetting to the default public base', { url });
128
+ PUBLIC_API_BASE_OVERRIDE = null;
129
+ }
130
+ else {
131
+ // Store WITHOUT a trailing slash: buildAugustUrl concatenates
132
+ // `${base}${relativeUrl}` (relativeUrl starts with '/'), so a trailing
133
+ // slash on the base would produce a double slash.
134
+ PUBLIC_API_BASE_OVERRIDE = url.replace(/\/+$/, '');
135
+ }
136
+ }
137
+ if (PUBLIC_API_BASE_OVERRIDE !== previous) {
138
+ // The public base moved (or reset). Drop cached public-catalog responses
139
+ // keyed against the previous base (see fetchTokenizedVault(s) etc.) so they
140
+ // aren't served for the new backend.
141
+ cache_1.CACHE.clear();
142
+ }
143
+ }
144
+ /**
145
+ * Read the active base for the `public` server — the SDK-level override if set,
146
+ * otherwise the compiled-in `WEBSERVER_URL.public`.
147
+ */
148
+ function getPublicApiBaseUrl() {
149
+ return PUBLIC_API_BASE_OVERRIDE ?? core_2.WEBSERVER_URL.public;
150
+ }
151
+ /**
152
+ * Combine the per-request timeout signal with any caller-supplied signal.
153
+ * Uses `AbortSignal.any` (Node 22+) with a manual relay fallback.
154
+ *
155
+ * Returns `timedOut()` (a closure over an internal flag set when the timeout
156
+ * fires) so the caller can distinguish "we timed out" from "caller cancelled",
157
+ * and `cleanup()` to release the fallback-relay listener.
158
+ */
159
+ function buildRequestAbortSignal(options) {
160
+ const timeoutMs = options?.timeoutMs ?? SDK_REQUEST_TIMEOUT_OVERRIDE ?? core_2.REQUEST_TIMEOUT_MS;
161
+ const timeoutController = new AbortController();
162
+ let didTimeout = false;
163
+ const timeoutId = setTimeout(() => {
164
+ didTimeout = true;
165
+ timeoutController.abort();
166
+ }, timeoutMs);
167
+ let signal = timeoutController.signal;
168
+ // No-op by default; replaced with a real listener-removal closure only when
169
+ // the manual relay fallback path below registers an 'abort' listener.
170
+ let relayCleanup = () => undefined;
171
+ if (options?.signal) {
172
+ // Capture in a local so the cleanup closure below keeps the non-nullable
173
+ // narrowing (a closure over `options.signal` would otherwise be re-widened).
174
+ const callerSignal = options.signal;
175
+ if (typeof AbortSignal.any === 'function') {
176
+ signal = AbortSignal.any([timeoutController.signal, callerSignal]);
177
+ }
178
+ else if (callerSignal.aborted) {
179
+ timeoutController.abort();
180
+ }
181
+ else {
182
+ const relay = () => timeoutController.abort();
183
+ callerSignal.addEventListener('abort', relay, { once: true });
184
+ relayCleanup = () => callerSignal.removeEventListener('abort', relay);
185
+ }
186
+ }
187
+ return {
188
+ signal,
189
+ timeoutId,
190
+ timeoutMs,
191
+ timedOut: () => didTimeout,
192
+ cleanup: () => {
193
+ clearTimeout(timeoutId);
194
+ relayCleanup();
195
+ },
196
+ };
197
+ }
198
+ let _overrideDeprecationWarned = false;
199
+ function warnOverrideDeprecation(callerTag) {
200
+ if (_overrideDeprecationWarned)
201
+ return;
202
+ _overrideDeprecationWarned = true;
203
+ // Deliberately a direct console.warn, not Logger.log.warn: a deprecation
204
+ // notice must surface in the integrator's console in every environment.
205
+ // Logger.log.warn would downgrade it to a prod-silent Sentry breadcrumb.
206
+ // biome-ignore lint/suspicious/noConsole: integrator-facing deprecation notice must surface in every environment; Logger.log.warn would downgrade it to a prod-silent Sentry breadcrumb.
207
+ console.warn(`[@augustdigital/sdk] ${callerTag}: option "override" is deprecated and will be removed in a future major version. Pass a valid apiKey instead.`);
208
+ }
209
+ /**
210
+ * LRU cache for API responses and frequently accessed data.
211
+ * 24-hour TTL with 1000 item capacity.
212
+ */
213
+ /**
214
+ * Read a response header tolerantly. Real `fetch` returns a `Headers` instance,
215
+ * but some test mocks supply a plain object; both shapes are supported here.
216
+ */
217
+ function readResponseHeader(headers, name) {
218
+ if (!headers)
219
+ return undefined;
220
+ const h = headers;
221
+ if (typeof h.get === 'function') {
222
+ return h.get(name) ?? undefined;
223
+ }
224
+ const v = headers[name];
225
+ return typeof v === 'string' ? v : undefined;
226
+ }
227
+ const cache_1 = require("./cache");
228
+ Object.defineProperty(exports, "CACHE", { enumerable: true, get: function () { return cache_1.CACHE; } });
229
+ Object.defineProperty(exports, "getSafeCache", { enumerable: true, get: function () { return cache_1.getSafeCache; } });
230
+ Object.defineProperty(exports, "setSafeCache", { enumerable: true, get: function () { return cache_1.setSafeCache; } });
231
+ /**
232
+ * Dedicated cache for token prices with short TTL to prevent rate limiting.
233
+ * 30-second TTL with 500 item capacity.
234
+ */
235
+ const PRICE_CACHE = new lru_cache_1.LRUCache({
236
+ max: 500,
237
+ ttl: 1000 * 30, // 30 seconds
238
+ allowStale: false,
239
+ });
240
+ /**
241
+ * Cache for failed price requests to prevent retry storms.
242
+ * 5-second TTL to allow quick retry after temporary failures.
243
+ */
244
+ const PRICE_ERROR_CACHE = new lru_cache_1.LRUCache({
245
+ max: 100,
246
+ ttl: 1000 * 5, // 5 seconds
247
+ allowStale: false,
248
+ });
249
+ /**
250
+ * In-flight price requests to prevent duplicate simultaneous API calls.
251
+ */
252
+ const PRICE_REQUESTS = new Map();
253
+ /**
254
+ * Build an August backend URL, rejecting unknown server keys and any
255
+ * `relativeUrl` that would escape the configured origin.
256
+ * Throws `AugustValidationError` with `code: 'INVALID_URL'`.
257
+ */
258
+ function buildAugustUrl(server, relativeUrl) {
259
+ const serverKey = server;
260
+ // The `public` base is overridable (setPublicApiBaseUrl / IAugustBase
261
+ // .publicApiBaseUrl) so non-prod deployments can point vault-catalog reads at
262
+ // an isolated backend. Resolved once here via getPublicApiBaseUrl() (single
263
+ // source of truth), so the origin check below validates against the OVERRIDDEN
264
+ // origin.
265
+ const base = serverKey === 'public' ? getPublicApiBaseUrl() : core_2.WEBSERVER_URL[serverKey];
266
+ if (!base) {
267
+ throw new errors_1.AugustValidationError('INVALID_URL', `Unknown August server "${String(server)}". Expected one of: ${Object.keys(core_2.WEBSERVER_URL).join(', ')}`);
268
+ }
269
+ if (typeof relativeUrl !== 'string' || relativeUrl.length === 0) {
270
+ throw new errors_1.AugustValidationError('INVALID_URL', 'relativeUrl must be a non-empty string');
271
+ }
272
+ // Reject anything that looks like a scheme or protocol-relative authority.
273
+ if (/^\s*[a-z][a-z0-9+.-]*:|^\s*\/\//i.test(relativeUrl)) {
274
+ throw new errors_1.AugustValidationError('INVALID_URL', `relativeUrl must be a path, not an absolute or protocol-relative URL`);
275
+ }
276
+ // Concat (rather than `new URL(rel, base)`) preserves base paths like /api/v1
277
+ // when relativeUrl starts with `/`. Origin check below is a second line.
278
+ const candidate = `${base}${relativeUrl}`;
279
+ let url;
280
+ try {
281
+ url = new URL(candidate);
282
+ }
283
+ catch {
284
+ throw new errors_1.AugustValidationError('INVALID_URL', `Invalid URL path: ${(0, sanitize_1.sanitizeString)(relativeUrl)}`);
285
+ }
286
+ const baseOrigin = new URL(base).origin;
287
+ if (url.origin !== baseOrigin) {
288
+ throw new errors_1.AugustValidationError('INVALID_URL', `URL origin mismatch: refusing to fetch ${url.origin} from a "${serverKey}" request scoped to ${baseOrigin}`);
289
+ }
290
+ return url.toString();
291
+ }
292
+ /**
293
+ * Make authenticated requests to August backend services using API key.
294
+ * Automatically logs errors with correlation IDs for debugging.
295
+ * @param apiKey - August API key for authentication
296
+ * @param relativeUrl - Endpoint path relative to base URL
297
+ * @param options - Request configuration including method and headers
298
+ * @returns Response object if successful
299
+ * @throws Error with correlation ID if request fails
300
+ */
301
+ async function fetchAugustWithKey(apiKey, relativeUrl, options) {
302
+ if (options?.override) {
303
+ warnOverrideDeprecation('fetchAugustWithKey');
304
+ }
305
+ if (!apiKey && !options?.override) {
306
+ throw new errors_1.AugustAuthError('AUTH_MISSING_KEY', 'fetchAugustWithKey: apiKey is required (set keys.august on the SDK constructor, or pass an explicit apiKey).');
307
+ }
308
+ const defaultHeaders = {
309
+ 'x-api-key': apiKey,
310
+ 'content-type': 'application/json',
311
+ accept: 'application/json',
312
+ };
313
+ const { signal: requestSignal, timeoutMs: effectiveTimeoutMs, timedOut, cleanup, } = buildRequestAbortSignal(options);
314
+ const startTime = performance.now();
315
+ const server = options?.server || 'production';
316
+ try {
317
+ const safeUrl = buildAugustUrl(server, relativeUrl);
318
+ const res = await fetch(safeUrl, {
319
+ headers: {
320
+ ...defaultHeaders,
321
+ ...options?.headers,
322
+ },
323
+ method: options?.method ?? 'GET',
324
+ body: JSON.stringify(options?.data),
325
+ signal: requestSignal,
326
+ });
327
+ cleanup();
328
+ // Track API call
329
+ (0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, res.status, server);
330
+ const correlationId = readResponseHeader(res.headers, 'x-correlation-id');
331
+ const logger = logger_1.Logger.getLogger();
332
+ if (!res.ok || res.status !== 200) {
333
+ if (correlationId && logger) {
334
+ logger.setTag('correlation_id', correlationId);
335
+ }
336
+ const error = errorFromResponseStatus(res.status, `Request failed: ${res.status}`, { correlationId });
337
+ logger?.captureException(error, { correlationId, status: res.status });
338
+ throw error;
339
+ }
340
+ return res;
341
+ }
342
+ catch (error) {
343
+ cleanup();
344
+ (0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, 0, server);
345
+ const err = error instanceof Error ? error : new Error(String(error));
346
+ if (err.name === 'AbortError') {
347
+ if (!timedOut()) {
348
+ throw err;
349
+ }
350
+ const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
351
+ logger_1.Logger.log.error('fetchAugustWithKey', timeoutError, { relativeUrl });
352
+ throw timeoutError;
353
+ }
354
+ throw err;
355
+ }
356
+ }
357
+ /**
358
+ * Make unauthenticated requests to August public API endpoints.
359
+ * Used for fetching vault metadata and public market data.
360
+ * @param relativeUrl - Endpoint path relative to public API base URL
361
+ * @param options - Request configuration including method and headers
362
+ * @returns Response object if successful
363
+ * @throws Error with correlation ID if request fails
364
+ */
365
+ async function fetchAugustPublic(relativeUrl, options) {
366
+ const defaultHeaders = {
367
+ 'content-type': 'application/json',
368
+ accept: 'application/json',
369
+ };
370
+ const { signal: requestSignal, timeoutMs: effectiveTimeoutMs, timedOut, cleanup, } = buildRequestAbortSignal(options);
371
+ const startTime = performance.now();
372
+ try {
373
+ const safeUrl = buildAugustUrl('public', relativeUrl);
374
+ const res = await fetch(safeUrl, {
375
+ headers: {
376
+ ...defaultHeaders,
377
+ ...options?.headers,
378
+ },
379
+ method: options?.method ?? 'GET',
380
+ body: JSON.stringify(options?.data),
381
+ signal: requestSignal,
382
+ });
383
+ cleanup();
384
+ (0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, res.status, 'public');
385
+ const correlationId = readResponseHeader(res.headers, 'x-correlation-id');
386
+ const logger = logger_1.Logger.getLogger();
387
+ if (!res.ok || res.status !== 200) {
388
+ if (correlationId && logger) {
389
+ logger.setTag('correlation_id', correlationId);
390
+ }
391
+ const error = errorFromResponseStatus(res.status, `Request failed: ${res.status}`, { correlationId });
392
+ logger?.captureException(error, { correlationId, status: res.status });
393
+ throw error;
394
+ }
395
+ return res;
396
+ }
397
+ catch (error) {
398
+ cleanup();
399
+ (0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, 0, 'public');
400
+ const err = error instanceof Error ? error : new Error(String(error));
401
+ if (err.name === 'AbortError') {
402
+ if (!timedOut()) {
403
+ throw err;
404
+ }
405
+ const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
406
+ logger_1.Logger.log.error('fetchAugustPublic', timeoutError, { relativeUrl });
407
+ throw timeoutError;
408
+ }
409
+ throw err;
410
+ }
411
+ }
412
+ /**
413
+ * Make authenticated requests using Bearer token authentication.
414
+ * Typically used for user-specific operations requiring OAuth tokens.
415
+ * @param bearerToken - OAuth bearer token
416
+ * @param relativeUrl - Endpoint path relative to base URL
417
+ * @param options - Request configuration including method and headers
418
+ * @returns Response object if successful
419
+ * @throws Error with correlation ID if request fails
420
+ */
421
+ async function fetchAugustWithBearer(bearerToken, relativeUrl, options) {
422
+ const defaultHeaders = {
423
+ authorization: `Bearer ${bearerToken}`,
424
+ 'content-type': 'application/json',
425
+ accept: 'application/json',
426
+ };
427
+ const { signal: requestSignal, timeoutMs: effectiveTimeoutMs, timedOut, cleanup, } = buildRequestAbortSignal(options);
428
+ const startTime = performance.now();
429
+ const server = options?.server ?? 'production';
430
+ try {
431
+ const safeUrl = buildAugustUrl(server, relativeUrl);
432
+ const res = await fetch(safeUrl, {
433
+ headers: {
434
+ ...defaultHeaders,
435
+ ...options?.headers,
436
+ },
437
+ method: options?.method ?? 'GET',
438
+ body: JSON.stringify(options?.data),
439
+ signal: requestSignal,
440
+ });
441
+ cleanup();
442
+ (0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, res.status, server);
443
+ const correlationId = readResponseHeader(res.headers, 'x-correlation-id');
444
+ const logger = logger_1.Logger.getLogger();
445
+ if (!res.ok || res.status !== 200) {
446
+ if (correlationId && logger) {
447
+ logger.setTag('correlation_id', correlationId);
448
+ }
449
+ const error = errorFromResponseStatus(res.status, `Request failed: ${res.status}`, { correlationId });
450
+ logger?.captureException(error, { correlationId, status: res.status });
451
+ throw error;
452
+ }
453
+ return res;
454
+ }
455
+ catch (error) {
456
+ cleanup();
457
+ (0, analytics_1.trackApiCall)(relativeUrl, options?.method ?? 'GET', startTime, 0, server);
458
+ const err = error instanceof Error ? error : new Error(String(error));
459
+ if (err.name === 'AbortError') {
460
+ if (!timedOut()) {
461
+ throw err;
462
+ }
463
+ const timeoutError = new errors_1.AugustTimeoutError((0, sanitize_1.sanitizeString)(`Request timeout after ${effectiveTimeoutMs / 1000}s: ${relativeUrl}`), effectiveTimeoutMs);
464
+ logger_1.Logger.log.error('fetchAugustWithBearer', timeoutError, { relativeUrl });
465
+ throw timeoutError;
466
+ }
467
+ throw err;
468
+ }
469
+ }
470
+ /**
471
+ * Check if an error is network-related and suitable for retry.
472
+ * Identifies timeouts, connection resets, and fetch failures.
473
+ */
474
+ function isRetryableError(error) {
475
+ return ((error instanceof TypeError && error.message.includes('fetch failed')) ||
476
+ error.name === 'AbortError' ||
477
+ error.message.includes('ETIMEDOUT') ||
478
+ error.message.includes('timeout') ||
479
+ error.message.includes('ECONNRESET') ||
480
+ error.message.includes('ENOTFOUND') ||
481
+ error.message.includes('ECONNREFUSED'));
482
+ }
483
+ /**
484
+ * Wrap async operations with exponential backoff retry logic.
485
+ * Retries on network errors with increasing delays between attempts.
486
+ * @param fn - Async function to execute with retry logic
487
+ * @param maxRetries - Maximum number of retry attempts
488
+ * @param baseDelay - Initial delay in milliseconds (doubles each retry)
489
+ * @param shouldRetry - Custom function to determine if error is retryable
490
+ * @returns Result of successful function execution
491
+ * @throws Last error if all retries exhausted
492
+ */
493
+ async function withRetry(fn, maxRetries = 3, baseDelay = 1000, shouldRetry = isRetryableError) {
494
+ let lastError;
495
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
496
+ try {
497
+ return await fn();
498
+ }
499
+ catch (error) {
500
+ lastError = error;
501
+ if (attempt < maxRetries && shouldRetry(error)) {
502
+ const delay = baseDelay * 2 ** attempt;
503
+ logger_1.Logger.log.warn('withRetry', `Attempt ${attempt + 1} failed, retrying in ${delay}ms: ${error.message}`);
504
+ await new Promise((resolve) => setTimeout(resolve, delay));
505
+ continue;
506
+ }
507
+ throw error;
508
+ }
509
+ }
510
+ // Unreachable in practice: the final attempt re-throws inside the loop. This
511
+ // satisfies the compiler's control-flow analysis without a non-null assertion.
512
+ throw lastError ?? new Error('withRetry exhausted retries without an error');
513
+ }
514
+ /**
515
+ * Fetch tokenized vault configurations from backend API.
516
+ * Results are cached to reduce API calls. Optionally filter by specific vault address.
517
+ * @param pool - Optional vault address to filter results
518
+ * @param headers - Monitoring headers for request tracking
519
+ * @returns Array of tokenized vault configurations
520
+ */
521
+ async function fetchTokenizedVault(pool, headers, loadSubaccounts, loadSnapshots) {
522
+ if (!pool) {
523
+ return [];
524
+ }
525
+ // Build cache key based on loading options
526
+ const keyParts = [`tokenized-vault-${pool}`];
527
+ if (loadSubaccounts === false)
528
+ keyParts.push('no-subaccounts');
529
+ if (loadSnapshots === false)
530
+ keyParts.push('no-snapshots');
531
+ const key = keyParts.join('-');
532
+ let tokenizedVault;
533
+ const cachedResponse = await (0, cache_1.getSafeCache)(key);
534
+ if (cachedResponse) {
535
+ tokenizedVault = cachedResponse;
536
+ }
537
+ if (!tokenizedVault) {
538
+ // Build endpoint URL with optional query parameters
539
+ let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.byVaultAddress(pool);
540
+ const params = new URLSearchParams();
541
+ if (loadSubaccounts === false) {
542
+ params.set('load_subaccounts', 'false');
543
+ }
544
+ if (loadSnapshots === false) {
545
+ params.set('load_snapshots', 'false');
546
+ }
547
+ const queryString = params.toString();
548
+ if (queryString) {
549
+ endpoint += `?${queryString}`;
550
+ }
551
+ const tokenizedVaultsResponse = await fetchAugustPublic(endpoint, {
552
+ headers: headers,
553
+ });
554
+ tokenizedVault = (await tokenizedVaultsResponse.json());
555
+ cache_1.CACHE.set(key, tokenizedVault, { ttl: 1000 * 60 * 10 }); // Cache for 10 minutes
556
+ }
557
+ // Filter by specific vault if address provided
558
+ if (pool &&
559
+ ((0, ethers_1.isAddress)(pool) || (0, chain_address_1.isSolanaAddress)(pool) || (0, chain_address_1.isStellarAddress)(pool))) {
560
+ return tokenizedVault ? [tokenizedVault] : [];
561
+ }
562
+ return [tokenizedVault];
563
+ }
564
+ /**
565
+ * Fetch tokenized vault configurations from backend API.
566
+ * Results are cached to reduce API calls. Optionally filter by specific vault address.
567
+ * @param pool - Optional vault address to filter results
568
+ * @param headers - Monitoring headers for request tracking
569
+ * @param loadSubaccounts - Optional flag to load subaccounts and EOA operators (defaults to true on API)
570
+ * @returns Array of tokenized vault configurations
571
+ */
572
+ async function fetchTokenizedVaults(pool, headers, loadSubaccounts, loadSnapshots) {
573
+ // Build cache key based on loading options
574
+ const keyParts = ['tokenized-vaults'];
575
+ if (pool)
576
+ keyParts.push(pool);
577
+ if (loadSubaccounts === false)
578
+ keyParts.push('no-subaccounts');
579
+ if (loadSnapshots === false)
580
+ keyParts.push('no-snapshots');
581
+ const key = keyParts.join('-');
582
+ let tokenizedVaults;
583
+ const cachedResponse = await (0, cache_1.getSafeCache)(key);
584
+ if (cachedResponse) {
585
+ tokenizedVaults = cachedResponse;
586
+ }
587
+ if (!tokenizedVaults) {
588
+ // Build endpoint URL with optional query parameters
589
+ let endpoint = core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.list;
590
+ const params = new URLSearchParams();
591
+ if (loadSubaccounts === false) {
592
+ params.set('load_subaccounts', 'false');
593
+ }
594
+ if (loadSnapshots === false) {
595
+ params.set('load_snapshots', 'false');
596
+ }
597
+ const queryString = params.toString();
598
+ if (queryString) {
599
+ endpoint += `?${queryString}`;
600
+ }
601
+ const tokenizedVaultsResponse = await fetchAugustPublic(endpoint, {
602
+ headers: headers,
603
+ });
604
+ tokenizedVaults =
605
+ (await tokenizedVaultsResponse.json());
606
+ const ttl = 1000 * 60 * 15; // 15 minute cache
607
+ cache_1.CACHE.set(key, tokenizedVaults, { ttl });
608
+ }
609
+ // Filter by specific vault if address provided
610
+ if (pool &&
611
+ ((0, ethers_1.isAddress)(pool) || (0, chain_address_1.isSolanaAddress)(pool) || (0, chain_address_1.isStellarAddress)(pool))) {
612
+ const foundObj = tokenizedVaults.find((t) => t.address.toLowerCase() === pool.toLowerCase());
613
+ return foundObj ? [foundObj] : [];
614
+ }
615
+ return tokenizedVaults;
616
+ }
617
+ /**
618
+ * Fetch current USD price for a token symbol or vault LP token.
619
+ * For vault LP tokens, calculates share price using totalAssets/totalSupply ratio.
620
+ * Falls back to CoinGecko if primary source fails.
621
+ * @param symbol - Token symbol or contract address
622
+ * @param provider - Optional web3 provider for on-chain price calculations
623
+ * @param coinGeckoKey - Optional CoinGecko API key for fallback pricing
624
+ * @param headers - Monitoring headers for request tracking
625
+ * @returns Token price in USD
626
+ */
627
+ async function fetchTokenPrice(symbol, provider, coinGeckoKey, headers) {
628
+ if (!symbol) {
629
+ logger_1.Logger.log.error('fetchTokenPrice', 'symbol parameter is undefined');
630
+ return 0;
631
+ }
632
+ // Normalize symbol and apply aliases BEFORE generating cache key
633
+ let normalizedSymbol = symbol.toLowerCase();
634
+ normalizedSymbol = normalizedSymbol === 'xbtc' ? 'btc' : normalizedSymbol;
635
+ normalizedSymbol = normalizedSymbol === 'strbtc' ? 'btc' : normalizedSymbol;
636
+ // Generate cache key based on normalized symbol and provider presence
637
+ const cacheKey = `price:${normalizedSymbol}:${provider ? 'with-provider' : 'no-provider'}`;
638
+ // Check error cache to prevent retry storms after failures
639
+ const cachedError = PRICE_ERROR_CACHE.get(cacheKey);
640
+ if (cachedError) {
641
+ logger_1.Logger.log.info('fetchTokenPrice', `Error cache HIT for ${normalizedSymbol} - throwing cached error`);
642
+ throw cachedError;
643
+ }
644
+ // Check price cache first to avoid rate limiting
645
+ const cachedPrice = PRICE_CACHE.get(cacheKey);
646
+ if (cachedPrice !== undefined) {
647
+ logger_1.Logger.log.info('fetchTokenPrice', `Cache HIT for ${normalizedSymbol}: $${cachedPrice}`);
648
+ return cachedPrice;
649
+ }
650
+ // Check for in-flight request to deduplicate simultaneous calls
651
+ const inflightRequest = PRICE_REQUESTS.get(cacheKey);
652
+ if (inflightRequest) {
653
+ logger_1.Logger.log.info('fetchTokenPrice', `In-flight request deduplication for ${normalizedSymbol}`);
654
+ return inflightRequest;
655
+ }
656
+ // Create the price fetching promise
657
+ const pricePromise = (async () => {
658
+ try {
659
+ const price = await _fetchTokenPriceInternal(symbol, provider, coinGeckoKey, headers);
660
+ // Cache the successful result
661
+ PRICE_CACHE.set(cacheKey, price);
662
+ // Clear any previous error cache on success
663
+ PRICE_ERROR_CACHE.delete(cacheKey);
664
+ return price;
665
+ }
666
+ catch (error) {
667
+ // Cache the error temporarily to prevent retry storms
668
+ const err = error instanceof Error ? error : new Error(String(error));
669
+ PRICE_ERROR_CACHE.set(cacheKey, err);
670
+ logger_1.Logger.log.info('fetchTokenPrice', `Cached error for ${normalizedSymbol}: ${err.message}`);
671
+ throw err;
672
+ }
673
+ finally {
674
+ // Clean up in-flight request tracking
675
+ PRICE_REQUESTS.delete(cacheKey);
676
+ }
677
+ })();
678
+ // Track this request to prevent duplicates
679
+ PRICE_REQUESTS.set(cacheKey, pricePromise);
680
+ return pricePromise;
681
+ }
682
+ // Normalize both raw integers to the same decimal scale BEFORE dividing —
683
+ // dividing the raw bigints first floors the ratio to ~1 and loses all
684
+ // fractional precision. Returns 1 for an empty vault (priced 1:1).
685
+ function normalizedSharePrice(totalAssets, totalSupply, decimals) {
686
+ const supply = Number((0, core_1.toNormalizedBn)(totalSupply, decimals).normalized);
687
+ if (!supply)
688
+ return 1;
689
+ return Number((0, core_1.toNormalizedBn)(totalAssets, decimals).normalized) / supply;
690
+ }
691
+ /**
692
+ * Internal price fetching implementation.
693
+ * This is separated to allow caching and request deduplication in the public function.
694
+ */
695
+ async function _fetchTokenPriceInternal(symbol, provider, coinGeckoKey, headers) {
696
+ // Fetch vault metadata to check if symbol is a vault LP token
697
+ const tokenizedVaults = await fetchTokenizedVaults(undefined, headers, false, false);
698
+ const vaultArray = tokenizedVaults.map((vault) => ({
699
+ vault: vault.address,
700
+ symbol: vault.receipt_token_symbol,
701
+ }));
702
+ const foundVaultLpAsset = vaultArray.find((v) => v.symbol?.toLowerCase() === symbol?.toLowerCase());
703
+ // @todo: handle multi-asset vaults
704
+ const tokenizedVault = tokenizedVaults.find((vault) => vault.address === foundVaultLpAsset?.vault);
705
+ const version = (0, vault_version_1.getVaultVersionV2)(tokenizedVault);
706
+ if (foundVaultLpAsset?.vault && provider && version === 'evm-2') {
707
+ try {
708
+ const vaultContract = new ethers_2.Contract((0, ethers_1.getAddress)(foundVaultLpAsset?.vault), abis_1.ABI_TOKENIZED_VAULT_V2, provider);
709
+ // Same bounded, no-fallback retry the write paths use for this selector
710
+ // (`getReceiptTokenAddressOrThrow` in `core/helpers/web3`). It cannot be
711
+ // reused here: `helpers/web3` imports `fetchTokenizedVault` from this
712
+ // module, so importing it back would be a circular dependency (CLAUDE.md
713
+ // §9). A transient empty `eth_call` response is absorbed; a vault that
714
+ // genuinely lacks `lpTokenAddress()` still falls into the catch below
715
+ // after the attempts are spent.
716
+ const receiptAddress = await (0, chain_error_1.retryOnTransientRpc)('fetchTokenPrice:receiptToken', () => vaultContract.lpTokenAddress(), { vault: foundVaultLpAsset.vault }, (error) => (0, chain_error_1.isRetryableRpcError)(error) ||
717
+ (0, chain_error_1.isEmptyViewResponse)(error, chain_error_1.LP_TOKEN_ADDRESS_SELECTOR));
718
+ const receiptContract = new ethers_2.Contract(receiptAddress, [web3_1.MIN_ABIS.decimals], provider);
719
+ const decimals = Number(await receiptContract.decimals());
720
+ const sharePrice = await vaultContract.getSharePrice();
721
+ return Number((0, core_1.toNormalizedBn)(sharePrice, decimals).normalized);
722
+ }
723
+ catch {
724
+ throw new Error('failed to fetch token price for evm-2 vault');
725
+ }
726
+ }
727
+ // Apply symbol normalization and aliases for API calls
728
+ let _symbol = symbol?.toLowerCase();
729
+ _symbol = _symbol === 'xbtc' ? 'btc' : _symbol;
730
+ _symbol = _symbol === 'strbtc' ? 'btc' : _symbol;
731
+ try {
732
+ // Fetch base token price from August backend
733
+ const res = await fetch(`https://prices.augustdigital.io/price/${_symbol}`, { headers: headers });
734
+ if (res.status !== 200) {
735
+ throw new Error(`fetching ${_symbol} price: ${res?.statusText}`);
736
+ }
737
+ const json = (await res.json());
738
+ // For vault LP tokens, calculate share price using on-chain ratio
739
+ if (foundVaultLpAsset && provider) {
740
+ const vaultContract = new ethers_2.Contract((0, ethers_1.getAddress)(foundVaultLpAsset.vault), abis_1.ABI_LENDING_POOL_V2, provider);
741
+ const [totalAssets, totalSupply, rawDecimals] = await Promise.all([
742
+ vaultContract.totalAssets(),
743
+ vaultContract.totalSupply(),
744
+ vaultContract.decimals(),
745
+ ]);
746
+ const decimals = Number(rawDecimals);
747
+ const sharePrice = normalizedSharePrice(totalAssets, totalSupply, decimals);
748
+ return json.price * sharePrice;
749
+ }
750
+ return json.price;
751
+ }
752
+ catch {
753
+ // Fallback to CoinGecko if primary source fails
754
+ const fallbackPrice = await (0, fetcher_1.fetchTokenPricesFromCoinGecko)(symbol, coinGeckoKey);
755
+ if (foundVaultLpAsset && provider) {
756
+ const vaultContract = new ethers_2.Contract((0, ethers_1.getAddress)(foundVaultLpAsset.vault), abis_1.ABI_LENDING_POOL_V2, provider);
757
+ const [totalAssets, totalSupply, rawDecimals] = await Promise.all([
758
+ vaultContract.totalAssets(),
759
+ vaultContract.totalSupply(),
760
+ vaultContract.decimals(),
761
+ ]);
762
+ const decimals = Number(rawDecimals);
763
+ const sharePrice = normalizedSharePrice(totalAssets, totalSupply, decimals);
764
+ return fallbackPrice * sharePrice;
765
+ }
766
+ if (fallbackPrice) {
767
+ return fallbackPrice;
768
+ }
769
+ else {
770
+ throw new Error('failed to fetch token price');
771
+ }
772
+ }
773
+ }
774
+ /**
775
+ * Fetch token price by contract address and chain ID from August price server.
776
+ * @param address - Token contract address
777
+ * @param chainId - Network chain ID
778
+ * @param headers - Optional monitoring headers for request tracking
779
+ * @returns Token price in USD, or 0 if not found
780
+ */
781
+ async function fetchTokenPriceByAddress(address, chainId, headers) {
782
+ if (!address || !chainId) {
783
+ return 0;
784
+ }
785
+ try {
786
+ const url = new URL(`${core_2.PRICE_SERVER_URL}/price_by_address_chain`);
787
+ url.searchParams.set('address', address);
788
+ url.searchParams.set('chain', chainId.toString());
789
+ url.searchParams.set('method', 'contract');
790
+ const res = await fetch(url.toString(), {
791
+ headers: {
792
+ accept: 'application/json',
793
+ ...headers,
794
+ },
795
+ });
796
+ if (res.status !== 200) {
797
+ throw new Error(`Failed to fetch price for ${address} on chain ${chainId}: ${res.statusText}`);
798
+ }
799
+ const json = (await res.json());
800
+ return json.price || 0;
801
+ }
802
+ catch (e) {
803
+ logger_1.Logger.log.warn('fetchTokenPriceByAddress', `Failed to fetch price for ${address} on chain ${chainId}: ${e}`);
804
+ return 0;
805
+ }
806
+ }
807
+ /**
808
+ * Fetch active loans for a specific vault from backend API.
809
+ * Results are cached per vault and chain to reduce API calls.
810
+ * @param pool - Vault address
811
+ * @param chainId - Network chain ID
812
+ * @param headers - Monitoring headers for request tracking
813
+ * @returns Array of active loan objects
814
+ */
815
+ async function fetchTokenizedVaultLoans(pool, chainId, headers) {
816
+ const key = `loans-${chainId}-${pool}`;
817
+ let loans;
818
+ const cached = await (0, cache_1.getSafeCache)(key);
819
+ if (cached) {
820
+ loans = cached;
821
+ }
822
+ else {
823
+ const tokenizedVaultsResponse = await fetchAugustPublic(core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.loans(pool, chainId, true), { headers: headers });
824
+ loans = (await tokenizedVaultsResponse.json()).loans;
825
+ await (0, cache_1.setSafeCache)(key, loans);
826
+ }
827
+ return loans?.filter((l) => l.state.toLowerCase() === 'active');
828
+ }
829
+ /**
830
+ * Fetch subaccount loans for a specific tokenized vault (lending pool).
831
+ * Retrieves all active subaccount loan data from the backend.
832
+ * @param pool - Vault address
833
+ * @param chainId - Network chain ID
834
+ * @param headers - Monitoring headers for request tracking
835
+ * @returns Array of active subaccount loan objects
836
+ */
837
+ async function fetchTokenizedVaultSubaccountLoans(pool, chainId, headers) {
838
+ const key = `subaccount-loans-${chainId}-${pool}`;
839
+ let loans;
840
+ const cached = await (0, cache_1.getSafeCache)(key);
841
+ if (cached) {
842
+ loans = cached;
843
+ }
844
+ else {
845
+ const tokenizedVaultsResponse = await fetchAugustPublic(core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.subaccountLoans(pool, chainId, true), { headers: headers });
846
+ loans = (await tokenizedVaultsResponse.json()).loans;
847
+ await (0, cache_1.setSafeCache)(key, loans);
848
+ }
849
+ return loans?.filter((l) => l.state.toLowerCase() === 'active');
850
+ }
851
+ /**
852
+ * Fetch historical timeseries data for a specific vault.
853
+ * Returns TVL, APY, PnL, and share price data over time.
854
+ * @param vaultAddress - Vault contract address
855
+ * @param nDays - Number of days of historical data to fetch (default 30, min 1)
856
+ * @param headers - Monitoring headers for request tracking
857
+ * @returns Historical timeseries data with date keys
858
+ */
859
+ async function fetchVaultHistoricalTimeseries(vaultAddress, nDays, headers) {
860
+ const key = `vault-historical-timeseries-${vaultAddress}-${nDays}`;
861
+ const cachedResponse = await (0, cache_1.getSafeCache)(key);
862
+ if (cachedResponse) {
863
+ return cachedResponse;
864
+ }
865
+ const response = await fetchAugustPublic(core_2.WEBSERVER_ENDPOINTS.public.tokenizedVault.historicalTimeseries(vaultAddress, nDays), { headers: headers });
866
+ if (!response.ok) {
867
+ throw new Error(`Failed to fetch historical timeseries data: ${response.statusText}`);
868
+ }
869
+ const json = (await response.json());
870
+ cache_1.CACHE.set(key, json, { ttl: 1000 * 60 * 10 }); // Cache for 10 minutes
871
+ return json;
872
+ }
873
+ /**
874
+ * Execute multiple promises with retry logic and allow partial failures.
875
+ * Unlike Promise.all, continues execution if some promises fail.
876
+ * Failed promises return null to maintain array index alignment.
877
+ * @param promises - Array of promises to execute
878
+ * @param maxRetries - Maximum retry attempts per promise
879
+ * @param baseDelay - Initial delay for exponential backoff
880
+ * @returns Array of results with null for failed promises
881
+ */
882
+ async function promiseSettle(promises, maxRetries = 3, baseDelay = 1000) {
883
+ const promisesWithRetry = promises.map((promise, index) => withRetry(async () => {
884
+ try {
885
+ return await promise;
886
+ }
887
+ catch (error) {
888
+ logger_1.Logger.log.warn('promiseSettle', `Promise at index ${index} failed`, error);
889
+ throw error;
890
+ }
891
+ }, maxRetries, baseDelay));
892
+ const results = await Promise.allSettled(promisesWithRetry);
893
+ return results.map((result, index) => {
894
+ if (result.status === 'fulfilled') {
895
+ return result.value;
896
+ }
897
+ else {
898
+ logger_1.Logger.log.warn('promiseSettle', `Promise at index ${index} failed after retries`, result.reason);
899
+ return null;
900
+ }
901
+ });
902
+ }
903
+ //# sourceMappingURL=fetcher.js.map