@upshiftfinance/sdk 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -2
  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 +953 -0
  40. package/lib/abis/SwapRouter.js +1228 -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 +249 -0
  65. package/lib/adapters/evm/index.d.ts +539 -0
  66. package/lib/adapters/evm/index.js +656 -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/confirm.d.ts +88 -0
  70. package/lib/adapters/solana/confirm.js +291 -0
  71. package/lib/adapters/solana/constants.d.ts +42 -0
  72. package/lib/adapters/solana/constants.js +59 -0
  73. package/lib/adapters/solana/getters.d.ts +42 -0
  74. package/lib/adapters/solana/getters.js +275 -0
  75. package/lib/adapters/solana/idl/vault-idl.d.ts +700 -0
  76. package/lib/adapters/solana/idl/vault-idl.js +2101 -0
  77. package/lib/adapters/solana/idl/withdrawal-queue-idl.d.ts +795 -0
  78. package/lib/adapters/solana/idl/withdrawal-queue-idl.js +1864 -0
  79. package/lib/adapters/solana/index.d.ts +372 -0
  80. package/lib/adapters/solana/index.js +459 -0
  81. package/lib/adapters/solana/pricing.d.ts +184 -0
  82. package/lib/adapters/solana/pricing.js +239 -0
  83. package/lib/adapters/solana/queue-hints.d.ts +29 -0
  84. package/lib/adapters/solana/queue-hints.js +59 -0
  85. package/lib/adapters/solana/queue.actions.d.ts +97 -0
  86. package/lib/adapters/solana/queue.actions.js +468 -0
  87. package/lib/adapters/solana/token-reads.d.ts +108 -0
  88. package/lib/adapters/solana/token-reads.js +145 -0
  89. package/lib/adapters/solana/types.d.ts +325 -0
  90. package/lib/adapters/solana/types.js +3 -0
  91. package/lib/adapters/solana/utils.d.ts +229 -0
  92. package/lib/adapters/solana/utils.js +773 -0
  93. package/lib/adapters/solana/vault.actions.d.ts +140 -0
  94. package/lib/adapters/solana/vault.actions.js +657 -0
  95. package/lib/adapters/solana/withdrawal-queue.d.ts +125 -0
  96. package/lib/adapters/solana/withdrawal-queue.js +301 -0
  97. package/lib/adapters/stellar/actions.d.ts +41 -0
  98. package/lib/adapters/stellar/actions.js +126 -0
  99. package/lib/adapters/stellar/constants.d.ts +43 -0
  100. package/lib/adapters/stellar/constants.js +53 -0
  101. package/lib/adapters/stellar/getters.d.ts +68 -0
  102. package/lib/adapters/stellar/getters.js +290 -0
  103. package/lib/adapters/stellar/index.d.ts +126 -0
  104. package/lib/adapters/stellar/index.js +187 -0
  105. package/lib/adapters/stellar/invocation.d.ts +55 -0
  106. package/lib/adapters/stellar/invocation.js +92 -0
  107. package/lib/adapters/stellar/soroban.d.ts +131 -0
  108. package/lib/adapters/stellar/soroban.js +617 -0
  109. package/lib/adapters/stellar/submit.d.ts +42 -0
  110. package/lib/adapters/stellar/submit.js +195 -0
  111. package/lib/adapters/stellar/types.d.ts +57 -0
  112. package/lib/adapters/stellar/types.js +6 -0
  113. package/lib/adapters/stellar/utils.d.ts +24 -0
  114. package/lib/adapters/stellar/utils.js +34 -0
  115. package/lib/adapters/sui/constants.d.ts +1 -0
  116. package/lib/adapters/sui/constants.js +9 -0
  117. package/lib/adapters/sui/getters.d.ts +24 -0
  118. package/lib/adapters/sui/getters.js +134 -0
  119. package/lib/adapters/sui/index.d.ts +53 -0
  120. package/lib/adapters/sui/index.js +96 -0
  121. package/lib/adapters/sui/transformer.d.ts +10 -0
  122. package/lib/adapters/sui/transformer.js +115 -0
  123. package/lib/adapters/sui/types.d.ts +70 -0
  124. package/lib/adapters/sui/types.js +3 -0
  125. package/lib/adapters/sui/utils.d.ts +8 -0
  126. package/lib/adapters/sui/utils.js +17 -0
  127. package/lib/core/analytics/app-name.d.ts +27 -0
  128. package/lib/core/analytics/app-name.js +48 -0
  129. package/lib/core/analytics/chain-name.d.ts +9 -0
  130. package/lib/core/analytics/chain-name.js +34 -0
  131. package/lib/core/analytics/constants.d.ts +15 -0
  132. package/lib/core/analytics/constants.js +28 -0
  133. package/lib/core/analytics/env.d.ts +46 -0
  134. package/lib/core/analytics/env.js +147 -0
  135. package/lib/core/analytics/index.d.ts +39 -0
  136. package/lib/core/analytics/index.js +83 -0
  137. package/lib/core/analytics/instrumentation.d.ts +29 -0
  138. package/lib/core/analytics/instrumentation.js +292 -0
  139. package/lib/core/analytics/method-taxonomy.d.ts +19 -0
  140. package/lib/core/analytics/method-taxonomy.js +156 -0
  141. package/lib/core/analytics/metrics.d.ts +48 -0
  142. package/lib/core/analytics/metrics.js +142 -0
  143. package/lib/core/analytics/sanitize.d.ts +57 -0
  144. package/lib/core/analytics/sanitize.js +272 -0
  145. package/lib/core/analytics/sentry-runtime.d.ts +15 -0
  146. package/lib/core/analytics/sentry-runtime.js +131 -0
  147. package/lib/core/analytics/sentry.d.ts +100 -0
  148. package/lib/core/analytics/sentry.js +696 -0
  149. package/lib/core/analytics/types.d.ts +55 -0
  150. package/lib/core/analytics/types.js +3 -0
  151. package/lib/core/analytics/user-identity.d.ts +55 -0
  152. package/lib/core/analytics/user-identity.js +218 -0
  153. package/lib/core/analytics/version.d.ts +6 -0
  154. package/lib/core/analytics/version.js +10 -0
  155. package/lib/core/attribution.d.ts +159 -0
  156. package/lib/core/attribution.js +194 -0
  157. package/lib/core/auth/index.d.ts +1 -0
  158. package/lib/core/auth/index.js +18 -0
  159. package/lib/core/auth/verify.d.ts +2 -0
  160. package/lib/core/auth/verify.js +35 -0
  161. package/lib/core/base.class.d.ts +193 -0
  162. package/lib/core/base.class.js +163 -0
  163. package/lib/core/cache.d.ts +9 -0
  164. package/lib/core/cache.js +31 -0
  165. package/lib/core/constants/adapters.d.ts +103 -0
  166. package/lib/core/constants/adapters.js +180 -0
  167. package/lib/core/constants/core.d.ts +162 -0
  168. package/lib/core/constants/core.js +281 -0
  169. package/lib/core/constants/swap-router.d.ts +180 -0
  170. package/lib/core/constants/swap-router.js +203 -0
  171. package/lib/core/constants/vaults.d.ts +93 -0
  172. package/lib/core/constants/vaults.js +277 -0
  173. package/lib/core/constants/web3.d.ts +106 -0
  174. package/lib/core/constants/web3.js +251 -0
  175. package/lib/core/errors/index.d.ts +177 -0
  176. package/lib/core/errors/index.js +257 -0
  177. package/lib/core/fetcher.d.ts +237 -0
  178. package/lib/core/fetcher.js +1103 -0
  179. package/lib/core/helpers/adapters.d.ts +13 -0
  180. package/lib/core/helpers/adapters.js +39 -0
  181. package/lib/core/helpers/chain-address.d.ts +13 -0
  182. package/lib/core/helpers/chain-address.js +47 -0
  183. package/lib/core/helpers/chain-error.d.ts +207 -0
  184. package/lib/core/helpers/chain-error.js +697 -0
  185. package/lib/core/helpers/chain-support.d.ts +98 -0
  186. package/lib/core/helpers/chain-support.js +139 -0
  187. package/lib/core/helpers/concurrency.d.ts +51 -0
  188. package/lib/core/helpers/concurrency.js +79 -0
  189. package/lib/core/helpers/core.d.ts +92 -0
  190. package/lib/core/helpers/core.js +368 -0
  191. package/lib/core/helpers/explorer-link.d.ts +16 -0
  192. package/lib/core/helpers/explorer-link.js +26 -0
  193. package/lib/core/helpers/multicall.d.ts +68 -0
  194. package/lib/core/helpers/multicall.js +103 -0
  195. package/lib/core/helpers/revert-decode.d.ts +248 -0
  196. package/lib/core/helpers/revert-decode.js +515 -0
  197. package/lib/core/helpers/signer.d.ts +61 -0
  198. package/lib/core/helpers/signer.js +184 -0
  199. package/lib/core/helpers/swap-router.d.ts +269 -0
  200. package/lib/core/helpers/swap-router.js +542 -0
  201. package/lib/core/helpers/vault-version.d.ts +24 -0
  202. package/lib/core/helpers/vault-version.js +83 -0
  203. package/lib/core/helpers/vaults.d.ts +89 -0
  204. package/lib/core/helpers/vaults.js +241 -0
  205. package/lib/core/helpers/web3.d.ts +366 -0
  206. package/lib/core/helpers/web3.js +1034 -0
  207. package/lib/core/index.d.ts +23 -0
  208. package/lib/core/index.js +40 -0
  209. package/lib/core/logger/curator-alert.d.ts +217 -0
  210. package/lib/core/logger/curator-alert.js +276 -0
  211. package/lib/core/logger/index.d.ts +99 -0
  212. package/lib/core/logger/index.js +163 -0
  213. package/lib/core/logger/slack.d.ts +49 -0
  214. package/lib/core/logger/slack.js +111 -0
  215. package/lib/core/vault-metadata.d.ts +12 -0
  216. package/lib/core/vault-metadata.js +42 -0
  217. package/lib/core/version-check.d.ts +58 -0
  218. package/lib/core/version-check.js +182 -0
  219. package/lib/evm/index.d.ts +2 -0
  220. package/lib/evm/index.js +19 -0
  221. package/lib/evm/methods/crossChainVault.d.ts +132 -0
  222. package/lib/evm/methods/crossChainVault.js +857 -0
  223. package/lib/evm/methods/crossChainVaultRegistry.d.ts +92 -0
  224. package/lib/evm/methods/crossChainVaultRegistry.js +239 -0
  225. package/lib/evm/methods/index.d.ts +2 -0
  226. package/lib/evm/methods/index.js +19 -0
  227. package/lib/evm/types/crossChain.d.ts +363 -0
  228. package/lib/evm/types/crossChain.js +20 -0
  229. package/lib/evm/types/index.d.ts +1 -0
  230. package/lib/evm/types/index.js +18 -0
  231. package/lib/index.d.ts +30 -0
  232. package/lib/index.js +52 -0
  233. package/lib/main.d.ts +596 -0
  234. package/lib/main.js +681 -0
  235. package/lib/modules/api/fetcher.d.ts +108 -0
  236. package/lib/modules/api/fetcher.js +187 -0
  237. package/lib/modules/api/index.d.ts +1 -0
  238. package/lib/modules/api/index.js +6 -0
  239. package/lib/modules/api/main.d.ts +587 -0
  240. package/lib/modules/api/main.js +911 -0
  241. package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
  242. package/lib/modules/sub-accounts/fetcher.js +96 -0
  243. package/lib/modules/sub-accounts/index.d.ts +2 -0
  244. package/lib/modules/sub-accounts/index.js +19 -0
  245. package/lib/modules/sub-accounts/main.d.ts +249 -0
  246. package/lib/modules/sub-accounts/main.js +211 -0
  247. package/lib/modules/sub-accounts/utils.d.ts +106 -0
  248. package/lib/modules/sub-accounts/utils.js +112 -0
  249. package/lib/modules/vaults/adapter.helpers.d.ts +84 -0
  250. package/lib/modules/vaults/adapter.helpers.js +202 -0
  251. package/lib/modules/vaults/fetcher.d.ts +147 -0
  252. package/lib/modules/vaults/fetcher.js +357 -0
  253. package/lib/modules/vaults/getters.d.ts +1060 -0
  254. package/lib/modules/vaults/getters.js +4079 -0
  255. package/lib/modules/vaults/index.d.ts +20 -0
  256. package/lib/modules/vaults/index.js +44 -0
  257. package/lib/modules/vaults/main.d.ts +607 -0
  258. package/lib/modules/vaults/main.js +1687 -0
  259. package/lib/modules/vaults/prefetch.d.ts +65 -0
  260. package/lib/modules/vaults/prefetch.js +120 -0
  261. package/lib/modules/vaults/read.actions.d.ts +406 -0
  262. package/lib/modules/vaults/read.actions.js +891 -0
  263. package/lib/modules/vaults/types.d.ts +149 -0
  264. package/lib/modules/vaults/types.js +3 -0
  265. package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
  266. package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
  267. package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
  268. package/lib/modules/vaults/utils/date-utils.js +84 -0
  269. package/lib/modules/vaults/utils.d.ts +153 -0
  270. package/lib/modules/vaults/utils.js +818 -0
  271. package/lib/modules/vaults/write.actions.d.ts +812 -0
  272. package/lib/modules/vaults/write.actions.js +2377 -0
  273. package/lib/polyfills.d.ts +1 -0
  274. package/lib/polyfills.js +12 -0
  275. package/lib/sdk.d.ts +30154 -0
  276. package/lib/services/coingecko/fetcher.d.ts +15 -0
  277. package/lib/services/coingecko/fetcher.js +67 -0
  278. package/lib/services/coingecko/index.d.ts +2 -0
  279. package/lib/services/coingecko/index.js +19 -0
  280. package/lib/services/coingecko/utils.d.ts +1 -0
  281. package/lib/services/coingecko/utils.js +24 -0
  282. package/lib/services/debank/fetcher.d.ts +126 -0
  283. package/lib/services/debank/fetcher.js +47 -0
  284. package/lib/services/debank/index.d.ts +2 -0
  285. package/lib/services/debank/index.js +19 -0
  286. package/lib/services/debank/utils.d.ts +50 -0
  287. package/lib/services/debank/utils.js +325 -0
  288. package/lib/services/layerzero/deposits.d.ts +55 -0
  289. package/lib/services/layerzero/deposits.js +174 -0
  290. package/lib/services/layerzero/redeems.d.ts +20 -0
  291. package/lib/services/layerzero/redeems.js +92 -0
  292. package/lib/services/layerzero/utils.d.ts +9 -0
  293. package/lib/services/layerzero/utils.js +22 -0
  294. package/lib/services/octavfi/fetcher.d.ts +33 -0
  295. package/lib/services/octavfi/fetcher.js +39 -0
  296. package/lib/services/octavfi/index.d.ts +3 -0
  297. package/lib/services/octavfi/index.js +20 -0
  298. package/lib/services/octavfi/types.d.ts +34 -0
  299. package/lib/services/octavfi/types.js +3 -0
  300. package/lib/services/octavfi/utils.d.ts +16 -0
  301. package/lib/services/octavfi/utils.js +244 -0
  302. package/lib/services/subgraph/fetcher.d.ts +2 -0
  303. package/lib/services/subgraph/fetcher.js +66 -0
  304. package/lib/services/subgraph/index.d.ts +2 -0
  305. package/lib/services/subgraph/index.js +19 -0
  306. package/lib/services/subgraph/schema.d.ts +48 -0
  307. package/lib/services/subgraph/schema.js +87 -0
  308. package/lib/services/subgraph/vaults.d.ts +83 -0
  309. package/lib/services/subgraph/vaults.js +1282 -0
  310. package/lib/services/swap-quotes/index.d.ts +105 -0
  311. package/lib/services/swap-quotes/index.js +77 -0
  312. package/lib/services/swap-quotes/paraswap.d.ts +51 -0
  313. package/lib/services/swap-quotes/paraswap.js +138 -0
  314. package/lib/services/untangled/fetcher.d.ts +40 -0
  315. package/lib/services/untangled/fetcher.js +110 -0
  316. package/lib/services/untangled/index.d.ts +3 -0
  317. package/lib/services/untangled/index.js +20 -0
  318. package/lib/services/untangled/types.d.ts +83 -0
  319. package/lib/services/untangled/types.js +10 -0
  320. package/lib/services/untangled/utils.d.ts +91 -0
  321. package/lib/services/untangled/utils.js +339 -0
  322. package/lib/types/api.d.ts +498 -0
  323. package/lib/types/api.js +3 -0
  324. package/lib/types/index.d.ts +12 -0
  325. package/lib/types/index.js +28 -0
  326. package/lib/types/points.d.ts +28 -0
  327. package/lib/types/points.js +3 -0
  328. package/lib/types/pools.d.ts +144 -0
  329. package/lib/types/pools.js +3 -0
  330. package/lib/types/staking.d.ts +28 -0
  331. package/lib/types/staking.js +3 -0
  332. package/lib/types/sub-accounts.d.ts +150 -0
  333. package/lib/types/sub-accounts.js +3 -0
  334. package/lib/types/subgraph.d.ts +84 -0
  335. package/lib/types/subgraph.js +3 -0
  336. package/lib/types/typed-contract.d.ts +102 -0
  337. package/lib/types/typed-contract.js +3 -0
  338. package/lib/types/user.d.ts +1 -0
  339. package/lib/types/user.js +3 -0
  340. package/lib/types/vaults.d.ts +886 -0
  341. package/lib/types/vaults.js +30 -0
  342. package/lib/types/web3.d.ts +81 -0
  343. package/lib/types/web3.js +14 -0
  344. package/lib/types/webserver.d.ts +730 -0
  345. package/lib/types/webserver.js +3 -0
  346. package/package.json +78 -3
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /**
3
+ * Shared LayerZero utilities
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.addressToBytes32 = addressToBytes32;
7
+ /**
8
+ * Convert Ethereum address to bytes32 format (left-padded with zeros)
9
+ * Used by LayerZero subgraph queries where addresses are stored in bytes32 format.
10
+ * @throws {Error} If address format is invalid
11
+ */
12
+ function addressToBytes32(address) {
13
+ // Validate address format
14
+ if (!address.match(/^0x[a-fA-F0-9]{40}$/)) {
15
+ throw new Error(`Invalid Ethereum address format: ${address}. Expected format: 0x followed by 40 hexadecimal characters.`);
16
+ }
17
+ // Remove 0x prefix and convert to lowercase
18
+ const cleanAddress = address.replace(/^0x/i, '').toLowerCase();
19
+ // Pad with 24 zeros (12 bytes) to make it 32 bytes total
20
+ return '0x' + '0'.repeat(24) + cleanAddress;
21
+ }
22
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,33 @@
1
+ import type { IAddress, IWSMonitorHeaders } from '../../types';
2
+ import type { IOctavfiPortfolio } from './types';
3
+ /**
4
+ * Response of the Upshift API's vault-level Octav endpoint.
5
+ *
6
+ * Keys are the vault's Solana operator addresses (case-sensitive base58).
7
+ * Values are the operator's raw Octav portfolio, or an `{ error }` object when
8
+ * the backend holds no usable portfolio for that operator.
9
+ */
10
+ export type IVaultOctavResponse = Record<string, IOctavfiPortfolio | {
11
+ error: string;
12
+ }>;
13
+ /**
14
+ * Fetch the Octav portfolios of every Solana operator of a vault in a single
15
+ * request to the Upshift public API.
16
+ *
17
+ * The API serves these from a cache that a backend cron refreshes, so this
18
+ * function never calls Octav and needs no Octav credentials. It makes exactly
19
+ * one HTTP request per call and never throws.
20
+ *
21
+ * @param vaultAddress - Vault address: EVM hex or Solana base58.
22
+ * @param headers - Optional monitoring headers forwarded with the request.
23
+ * @returns Dictionary of operator address to portfolio or error on a 200 or
24
+ * 207 (partial success) response; `false` on any other status or when the
25
+ * request fails.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const response = await fetchVaultOctavResponse(vaultAddress);
30
+ * const portfolio = response ? response[borrower] : undefined;
31
+ * ```
32
+ */
33
+ export declare function fetchVaultOctavResponse(vaultAddress: IAddress, headers?: IWSMonitorHeaders): Promise<IVaultOctavResponse | false>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchVaultOctavResponse = fetchVaultOctavResponse;
4
+ const core_1 = require("../../core");
5
+ /**
6
+ * Fetch the Octav portfolios of every Solana operator of a vault in a single
7
+ * request to the Upshift public API.
8
+ *
9
+ * The API serves these from a cache that a backend cron refreshes, so this
10
+ * function never calls Octav and needs no Octav credentials. It makes exactly
11
+ * one HTTP request per call and never throws.
12
+ *
13
+ * @param vaultAddress - Vault address: EVM hex or Solana base58.
14
+ * @param headers - Optional monitoring headers forwarded with the request.
15
+ * @returns Dictionary of operator address to portfolio or error on a 200 or
16
+ * 207 (partial success) response; `false` on any other status or when the
17
+ * request fails.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const response = await fetchVaultOctavResponse(vaultAddress);
22
+ * const portfolio = response ? response[borrower] : undefined;
23
+ * ```
24
+ */
25
+ async function fetchVaultOctavResponse(vaultAddress, headers) {
26
+ try {
27
+ const response = await (0, core_1.fetchUpshiftPublic)(core_1.WEBSERVER_ENDPOINTS.public.tokenizedVault.octav(vaultAddress), { headers: headers });
28
+ if (response.status === 200 || response.status === 207) {
29
+ return (await response.json());
30
+ }
31
+ core_1.Logger.log.error('fetchVaultOctavResponse', new Error(`HTTP ${response.status} ${response.statusText}`), { status: response.status, statusText: response.statusText });
32
+ return false;
33
+ }
34
+ catch (e) {
35
+ core_1.Logger.log.error('fetchVaultOctavResponse', e);
36
+ return false;
37
+ }
38
+ }
39
+ //# sourceMappingURL=fetcher.js.map
@@ -0,0 +1,3 @@
1
+ export * from './fetcher';
2
+ export * from './types';
3
+ export * from './utils';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./fetcher"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ __exportStar(require("./utils"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,34 @@
1
+ import type { IAddress } from '../../types';
2
+ export type IOctavfiEndpoint = 'portfolio';
3
+ export interface IOctavfiAsset {
4
+ balance: string;
5
+ symbol: string;
6
+ price: string;
7
+ value: string;
8
+ contractAddress?: IAddress;
9
+ chain: string;
10
+ }
11
+ export interface IOctavfiProtocolBreakdown {
12
+ key: string;
13
+ name: string;
14
+ value: string;
15
+ assets: IOctavfiAsset[];
16
+ }
17
+ export interface IOctavfiChainBreakdown {
18
+ key: string;
19
+ name: string;
20
+ value: string;
21
+ protocols: string[];
22
+ }
23
+ export interface IOctavfiPortfolio {
24
+ address: IAddress;
25
+ cashBalance: string;
26
+ dailyIncome: string;
27
+ dailyExpense: string;
28
+ fees: string;
29
+ feesFiat: string;
30
+ lastUpdated: string;
31
+ networth: string;
32
+ assetByProtocols: Record<string, IOctavfiProtocolBreakdown>;
33
+ chains: Record<string, IOctavfiChainBreakdown>;
34
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,16 @@
1
+ import type { IOctavfiPortfolio } from './types';
2
+ import type { IDebankNormalizedResponse } from '../debank/utils';
3
+ /**
4
+ * Transforms Octavfi portfolio response to DeBank-compatible format.
5
+ * This allows Solana addresses to use Octavfi data while maintaining
6
+ * compatibility with existing DeBank parsing functions.
7
+ *
8
+ * @param octavfiPortfolio - Octavfi portfolio response
9
+ * @returns DeBank-compatible response structure
10
+ */
11
+ export declare function transformOctavfiToDebank(octavfiPortfolio: IOctavfiPortfolio | null | undefined): IDebankNormalizedResponse;
12
+ /**
13
+ * Transforms multiple Octavfi portfolios to DeBank format.
14
+ * Used when fetching multiple addresses.
15
+ */
16
+ export declare function transformOctavfiPortfoliosToDebank(portfolios: IOctavfiPortfolio[]): IDebankNormalizedResponse[];
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformOctavfiToDebank = transformOctavfiToDebank;
4
+ exports.transformOctavfiPortfoliosToDebank = transformOctavfiPortfoliosToDebank;
5
+ /**
6
+ * Transforms Octavfi portfolio response to DeBank-compatible format.
7
+ * This allows Solana addresses to use Octavfi data while maintaining
8
+ * compatibility with existing DeBank parsing functions.
9
+ *
10
+ * @param octavfiPortfolio - Octavfi portfolio response
11
+ * @returns DeBank-compatible response structure
12
+ */
13
+ function transformOctavfiToDebank(octavfiPortfolio) {
14
+ if (!octavfiPortfolio) {
15
+ return {
16
+ subaccount: {
17
+ positions: [],
18
+ tokens: [],
19
+ },
20
+ };
21
+ }
22
+ const positions = [];
23
+ const tokens = [];
24
+ // Transform protocols (assetByProtocols) into DeBank positions format
25
+ const assetByProtocols = octavfiPortfolio.assetByProtocols || {};
26
+ Object.entries(assetByProtocols).forEach(([protocolKey, protocol]) => {
27
+ // Skip wallet protocol - we'll handle it separately in tokens
28
+ if (protocolKey === 'wallet') {
29
+ return;
30
+ }
31
+ const { supplyAssets, borrowAssets } = collectProtocolLegs(protocol);
32
+ // Octav's protocol value is already net of debt, so it stays the net and
33
+ // the borrow legs are added back to give the gross supplied value.
34
+ const netUsdValue = parseFloat(protocol.value || '0') || 0;
35
+ const debtUsdValue = borrowAssets.reduce((sum, asset) => sum + assetUsdValue(asset), 0);
36
+ // Create position structure matching DeBank format
37
+ const position = {
38
+ id: protocolKey,
39
+ chain: getChainFromProtocol(protocol, octavfiPortfolio),
40
+ name: protocol.name || protocolKey,
41
+ logo_url: '', // Octavfi doesn't provide protocol logos
42
+ site_url: '', // Octavfi doesn't provide protocol URLs
43
+ portfolio_item_list: [
44
+ {
45
+ name: protocol.name || protocolKey,
46
+ stats: {
47
+ asset_usd_value: netUsdValue + debtUsdValue,
48
+ debt_usd_value: debtUsdValue,
49
+ net_usd_value: netUsdValue,
50
+ },
51
+ detail: {
52
+ supply_token_list: supplyAssets
53
+ .map((asset) => transformAssetToDebankToken(asset, 'supply'))
54
+ .filter((token) => token !== null),
55
+ borrow_token_list: borrowAssets
56
+ .map((asset) => transformAssetToDebankToken(asset, 'borrow'))
57
+ .filter((token) => token !== null),
58
+ },
59
+ },
60
+ ],
61
+ };
62
+ positions.push(position);
63
+ });
64
+ // Transform wallet assets to tokens array
65
+ const walletProtocol = assetByProtocols['wallet'];
66
+ if (walletProtocol && walletProtocol.chains) {
67
+ // Extract assets from nested structure: chains -> protocolPositions -> assets
68
+ Object.values(walletProtocol.chains).forEach((chain) => {
69
+ if (chain.protocolPositions) {
70
+ Object.values(chain.protocolPositions).forEach((protocolPosition) => {
71
+ if (protocolPosition.assets &&
72
+ Array.isArray(protocolPosition.assets)) {
73
+ protocolPosition.assets.forEach((asset) => {
74
+ tokens.push({
75
+ ...transformAssetToDebankToken(asset, 'wallet'),
76
+ is_wallet: true,
77
+ is_core: true, // Assume wallet tokens are core tokens
78
+ });
79
+ });
80
+ }
81
+ });
82
+ }
83
+ });
84
+ }
85
+ // Also add protocol assets as tokens (non-wallet). Deliberately walks only
86
+ // `assets`, not the lending `supplyAssets`/`borrowAssets` legs that
87
+ // `collectProtocolLegs` puts on the positions above: downstream parsers
88
+ // count `tokens` as wallet holdings, so adding the legs here would count
89
+ // collateral twice and report debt as a positive holding.
90
+ Object.entries(assetByProtocols).forEach(([protocolKey, protocol]) => {
91
+ if (protocolKey === 'wallet')
92
+ return;
93
+ if (!protocol || !protocol.chains)
94
+ return;
95
+ // Extract assets from nested structure
96
+ Object.values(protocol.chains).forEach((chain) => {
97
+ if (chain.protocolPositions) {
98
+ Object.values(chain.protocolPositions).forEach((protocolPosition) => {
99
+ // Direct assets
100
+ if (protocolPosition.assets &&
101
+ Array.isArray(protocolPosition.assets)) {
102
+ protocolPosition.assets.forEach((asset) => {
103
+ // Check if token already exists (from wallet)
104
+ const existingToken = tokens.find((t) => t.symbol === asset.symbol &&
105
+ t.chain === (asset.chainKey || asset.chain));
106
+ if (!existingToken) {
107
+ tokens.push({
108
+ ...transformAssetToDebankToken(asset, 'supply'),
109
+ is_wallet: false,
110
+ is_core: true, // Assume protocol tokens are core
111
+ });
112
+ }
113
+ });
114
+ }
115
+ // Nested protocolPositions (like in Kamino)
116
+ if (protocolPosition.protocolPositions &&
117
+ Array.isArray(protocolPosition.protocolPositions)) {
118
+ protocolPosition.protocolPositions.forEach((nestedPos) => {
119
+ if (nestedPos.assets && Array.isArray(nestedPos.assets)) {
120
+ nestedPos.assets.forEach((asset) => {
121
+ const existingToken = tokens.find((t) => t.symbol === asset.symbol &&
122
+ t.chain === (asset.chainKey || asset.chain));
123
+ if (!existingToken) {
124
+ tokens.push({
125
+ ...transformAssetToDebankToken(asset, 'supply'),
126
+ is_wallet: false,
127
+ is_core: true,
128
+ });
129
+ }
130
+ });
131
+ }
132
+ });
133
+ }
134
+ });
135
+ }
136
+ });
137
+ });
138
+ return {
139
+ subaccount: {
140
+ positions,
141
+ tokens,
142
+ },
143
+ };
144
+ }
145
+ /**
146
+ * Collects a protocol's supply and borrow legs across its chains and position
147
+ * groups.
148
+ *
149
+ * Octav nests positions as `chains -> protocolPositions -> group`, where a
150
+ * group holds plain `assets` (vault shares) or a list of positions. A lending
151
+ * position (a Kamino obligation) keeps its collateral in `supplyAssets` and its
152
+ * debt in `borrowAssets` rather than in `assets`; reading only `assets` gave a
153
+ * lending position its net value with no collateral or debt behind it.
154
+ *
155
+ * @param protocol - One entry of a portfolio's `assetByProtocols`
156
+ * @returns The supply legs (plain and collateral assets) and the borrow legs
157
+ */
158
+ function collectProtocolLegs(protocol) {
159
+ const supplyAssets = [];
160
+ const borrowAssets = [];
161
+ const collect = (position) => {
162
+ for (const key of ['assets', 'supplyAssets']) {
163
+ if (Array.isArray(position?.[key]))
164
+ supplyAssets.push(...position[key]);
165
+ }
166
+ if (Array.isArray(position?.borrowAssets)) {
167
+ borrowAssets.push(...position.borrowAssets);
168
+ }
169
+ };
170
+ Object.values(protocol?.chains ?? {}).forEach((chain) => {
171
+ Object.values(chain?.protocolPositions ?? {}).forEach((group) => {
172
+ collect(group);
173
+ // Nested protocolPositions (like in Kamino)
174
+ if (Array.isArray(group?.protocolPositions)) {
175
+ group.protocolPositions.forEach(collect);
176
+ }
177
+ });
178
+ });
179
+ return { supplyAssets, borrowAssets };
180
+ }
181
+ /**
182
+ * An Octav asset's USD value: its `value` when present, else balance × price.
183
+ */
184
+ function assetUsdValue(asset) {
185
+ const value = parseFloat(asset?.value);
186
+ if (Number.isFinite(value))
187
+ return value;
188
+ return (parseFloat(asset?.balance) || 0) * (parseFloat(asset?.price) || 0);
189
+ }
190
+ /**
191
+ * Transforms Octavfi asset to DeBank token format
192
+ */
193
+ function transformAssetToDebankToken(asset, // Using any since the actual structure differs from IOctavfiAsset
194
+ exposureType) {
195
+ if (!asset) {
196
+ return null;
197
+ }
198
+ const balance = parseFloat(asset.balance || '0') || 0;
199
+ const price = parseFloat(asset.price || '0') || 0;
200
+ const amount = balance;
201
+ const chain = asset.chainKey || asset.chain || 'unknown';
202
+ const contract = asset.contract || asset.chainContract || asset.contractAddress;
203
+ const decimals = parseInt(asset.decimal || asset.decimals || '18', 10);
204
+ return {
205
+ id: contract || asset.symbol || 'unknown', // Use contract address if available, fallback to symbol
206
+ chain: chain,
207
+ name: asset.name || asset.symbol || 'Unknown',
208
+ symbol: asset.symbol || 'UNKNOWN',
209
+ optimized_symbol: asset.symbol || 'UNKNOWN',
210
+ decimals: decimals,
211
+ logo_url: '', // Octavfi doesn't provide token logos
212
+ amount,
213
+ price,
214
+ protocol_id: '', // Will be set by the calling context
215
+ supplying_exposure: exposureType === 'supply' ? 'true' : undefined,
216
+ };
217
+ }
218
+ /**
219
+ * Determines the chain from protocol data or portfolio chains
220
+ */
221
+ function getChainFromProtocol(protocol, portfolio) {
222
+ // Try to get chain from protocol.chains structure
223
+ if (protocol.chains) {
224
+ const chainKeys = Object.keys(protocol.chains);
225
+ if (chainKeys.length > 0) {
226
+ return chainKeys[0];
227
+ }
228
+ }
229
+ // Fallback to first chain in portfolio
230
+ const chains = portfolio.chains || {};
231
+ const chainKeys = Object.keys(chains);
232
+ if (chainKeys.length > 0) {
233
+ return chainKeys[0];
234
+ }
235
+ return 'unknown';
236
+ }
237
+ /**
238
+ * Transforms multiple Octavfi portfolios to DeBank format.
239
+ * Used when fetching multiple addresses.
240
+ */
241
+ function transformOctavfiPortfoliosToDebank(portfolios) {
242
+ return portfolios.map(transformOctavfiToDebank);
243
+ }
244
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,2 @@
1
+ export declare function fetchSubgraph(graphUrl: string, query: string, apiKey?: string): Promise<Response>;
2
+ export declare function fetchSubgraphWithRetry(graphUrl: string, query: string, apiKey?: string, maxRetries?: number, baseDelay?: number): Promise<Response>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchSubgraph = fetchSubgraph;
4
+ exports.fetchSubgraphWithRetry = fetchSubgraphWithRetry;
5
+ const core_1 = require("../../core");
6
+ async function fetchSubgraph(graphUrl, query, apiKey) {
7
+ return fetchSubgraphWithRetry(graphUrl, query, apiKey);
8
+ }
9
+ async function fetchSubgraphWithRetry(graphUrl, query, apiKey, maxRetries = 3, baseDelay = 1000) {
10
+ if (!graphUrl) {
11
+ throw new Error('#fetchSubgraph: URL is not defined');
12
+ }
13
+ let lastError;
14
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
15
+ try {
16
+ // Abort a hung subgraph request after the SDK-wide REQUEST_TIMEOUT_MS
17
+ // (15 s). The retry loop below re-arms a fresh timer per attempt.
18
+ const controller = new AbortController();
19
+ const timeoutId = setTimeout(() => controller.abort(), core_1.REQUEST_TIMEOUT_MS);
20
+ try {
21
+ const headers = {
22
+ 'Content-Type': 'application/json',
23
+ };
24
+ if (apiKey) {
25
+ headers['Authorization'] = `Bearer ${apiKey}`;
26
+ }
27
+ const response = await fetch(graphUrl, {
28
+ method: 'POST',
29
+ headers,
30
+ body: JSON.stringify({
31
+ query: `query ${query}`,
32
+ }),
33
+ signal: controller.signal,
34
+ });
35
+ clearTimeout(timeoutId);
36
+ return response;
37
+ }
38
+ catch (fetchError) {
39
+ clearTimeout(timeoutId);
40
+ throw fetchError;
41
+ }
42
+ }
43
+ catch (error) {
44
+ lastError = error;
45
+ // Retry only transient failures (network drop, abort/timeout) while we
46
+ // have retries left. `fetch` can reject with non-Error values (e.g. a
47
+ // string from a polyfill), so narrow before touching `.message`.
48
+ const isRetryable = error instanceof Error &&
49
+ ((error instanceof TypeError &&
50
+ error.message.includes('fetch failed')) ||
51
+ error.name === 'AbortError' ||
52
+ error.message.includes('ETIMEDOUT') ||
53
+ error.message.includes('timeout'));
54
+ if (attempt < maxRetries && isRetryable) {
55
+ const delay = baseDelay * 2 ** attempt; // Exponential backoff
56
+ core_1.Logger.log.warn(`fetchSubgraph`, `${graphUrl?.includes('/subgraphs') ? graphUrl?.split('/subgraphs/')?.[1]?.split('/')?.[0] : graphUrl}: Attempt ${attempt + 1} failed, retrying in ${delay}ms`);
57
+ await new Promise((resolve) => setTimeout(resolve, delay));
58
+ continue;
59
+ }
60
+ // If it's not a retryable error or we're out of retries, throw
61
+ throw error;
62
+ }
63
+ }
64
+ throw lastError;
65
+ }
66
+ //# sourceMappingURL=fetcher.js.map
@@ -0,0 +1,2 @@
1
+ export * from './vaults';
2
+ export * from './fetcher';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./vaults"), exports);
18
+ __exportStar(require("./fetcher"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Which field-naming schema a deployed Upshift vault subgraph uses:
3
+ * - `'old'` — snake_case fields (`block_number`, `timestamp_`, `transactionHash_`).
4
+ * - `'new'` — camelCase fields (`blockNumber`, `blockTimestamp`, `transactionHash`).
5
+ *
6
+ * The two templates are otherwise equivalent; the SDK aliases new-schema fields
7
+ * back to the old internal names when querying, so the rest of the code only ever
8
+ * sees the old (snake_case) shape.
9
+ */
10
+ export type SubgraphSchema = 'old' | 'new';
11
+ /**
12
+ * True when a GraphQL error array reports an unknown field on the queried type
13
+ * (message contains "has no field") — the signature of a schema mismatch.
14
+ *
15
+ * @param errors - GraphQL `errors` array from a subgraph response (may be undefined).
16
+ * @returns `true` if any error message indicates an unknown field, else `false`.
17
+ */
18
+ export declare function isSubgraphSchemaFieldError(errors: {
19
+ message?: string;
20
+ }[] | undefined): boolean;
21
+ /**
22
+ * Detects whether a deployed subgraph uses the old or new field schema by probing
23
+ * a single field (`blockTimestamp`) that exists only on the new template, on
24
+ * `withdrawalRequesteds`, or on `transfers` for a receipt-token subgraph that
25
+ * has no `withdrawalRequesteds` entity.
26
+ *
27
+ * This replaces the previous heuristic — "vault symbol present in the deprecated
28
+ * `SUBGRAPH_VAULT_URLS` map ⇒ old schema, else new" — which mis-guessed any
29
+ * newly-added vault whose subgraph shipped on the old template (e.g.
30
+ * `august-citrea-earn-ctusd`). A wrong guess made every subgraph read query
31
+ * non-existent field names, so the subgraph returned GraphQL errors with no
32
+ * `data` and the SDK silently returned empty sets — emptying the Pending
33
+ * Withdrawals and History tabs for that vault.
34
+ *
35
+ * Because the schema is immutable for a fixed subgraph deployment, the result is
36
+ * cached per URL ({@link SCHEMA_TTL_MS}); across a page's positions/history/
37
+ * withdrawals reads this amounts to a single extra lightweight query per subgraph.
38
+ *
39
+ * Side effects: at most two HTTP POSTs to the subgraph per URL per TTL window
40
+ * (the second only for a subgraph without `withdrawalRequesteds`).
41
+ *
42
+ * @param goldskyUrl - Fully-qualified subgraph GraphQL endpoint.
43
+ * @param apiKey - Optional Goldsky API key sent as a Bearer token.
44
+ * @returns `'old'` or `'new'`. Defaults to `'new'` when the URL is empty or the
45
+ * probe is inconclusive (network error / unexpected response) — the schema the
46
+ * majority of current vaults use.
47
+ */
48
+ export declare function resolveSubgraphSchema(goldskyUrl: string, apiKey?: string): Promise<SubgraphSchema>;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSubgraphSchemaFieldError = isSubgraphSchemaFieldError;
4
+ exports.resolveSubgraphSchema = resolveSubgraphSchema;
5
+ const core_1 = require("../../core");
6
+ const fetcher_1 = require("./fetcher");
7
+ const SCHEMA_CACHE_PREFIX = 'subgraph-schema-';
8
+ // A subgraph's schema is fixed for a given deployment/version, so one probe can
9
+ // serve every subsequent read for a long time. Cache generously.
10
+ const SCHEMA_TTL_MS = 60 * 60 * 1000; // 1 hour
11
+ /**
12
+ * True when a GraphQL error array reports an unknown field on the queried type
13
+ * (message contains "has no field") — the signature of a schema mismatch.
14
+ *
15
+ * @param errors - GraphQL `errors` array from a subgraph response (may be undefined).
16
+ * @returns `true` if any error message indicates an unknown field, else `false`.
17
+ */
18
+ function isSubgraphSchemaFieldError(errors) {
19
+ return Boolean(errors?.some((e) => e?.message?.includes('has no field')));
20
+ }
21
+ // GraphQL errors from querying `blockTimestamp` on one row of `entity`;
22
+ // undefined on a non-200 response or a clean result.
23
+ async function probeSchemaErrors(goldskyUrl, entity, apiKey) {
24
+ const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, `{ ${entity}(first: 1) { blockTimestamp } }`, apiKey);
25
+ if (result.status !== 200)
26
+ return undefined;
27
+ const json = (await result.json());
28
+ return json?.errors;
29
+ }
30
+ /**
31
+ * Detects whether a deployed subgraph uses the old or new field schema by probing
32
+ * a single field (`blockTimestamp`) that exists only on the new template, on
33
+ * `withdrawalRequesteds`, or on `transfers` for a receipt-token subgraph that
34
+ * has no `withdrawalRequesteds` entity.
35
+ *
36
+ * This replaces the previous heuristic — "vault symbol present in the deprecated
37
+ * `SUBGRAPH_VAULT_URLS` map ⇒ old schema, else new" — which mis-guessed any
38
+ * newly-added vault whose subgraph shipped on the old template (e.g.
39
+ * `august-citrea-earn-ctusd`). A wrong guess made every subgraph read query
40
+ * non-existent field names, so the subgraph returned GraphQL errors with no
41
+ * `data` and the SDK silently returned empty sets — emptying the Pending
42
+ * Withdrawals and History tabs for that vault.
43
+ *
44
+ * Because the schema is immutable for a fixed subgraph deployment, the result is
45
+ * cached per URL ({@link SCHEMA_TTL_MS}); across a page's positions/history/
46
+ * withdrawals reads this amounts to a single extra lightweight query per subgraph.
47
+ *
48
+ * Side effects: at most two HTTP POSTs to the subgraph per URL per TTL window
49
+ * (the second only for a subgraph without `withdrawalRequesteds`).
50
+ *
51
+ * @param goldskyUrl - Fully-qualified subgraph GraphQL endpoint.
52
+ * @param apiKey - Optional Goldsky API key sent as a Bearer token.
53
+ * @returns `'old'` or `'new'`. Defaults to `'new'` when the URL is empty or the
54
+ * probe is inconclusive (network error / unexpected response) — the schema the
55
+ * majority of current vaults use.
56
+ */
57
+ async function resolveSubgraphSchema(goldskyUrl, apiKey) {
58
+ if (!goldskyUrl)
59
+ return 'new';
60
+ const key = `${SCHEMA_CACHE_PREFIX}${goldskyUrl}`;
61
+ const cached = core_1.CACHE.get(key);
62
+ if (cached)
63
+ return cached;
64
+ try {
65
+ // `blockTimestamp` is a new-schema-only field. If the subgraph rejects it
66
+ // with an unknown-field error, the deployment is old-schema. Schema
67
+ // validation is static, so this is authoritative even when the entity has
68
+ // zero rows. A receipt-token subgraph indexes only `transfers`, so when
69
+ // `withdrawalRequesteds` itself is unknown the probe moves to `transfers`.
70
+ let errors = await probeSchemaErrors(goldskyUrl, 'withdrawalRequesteds', apiKey);
71
+ if (errors?.some((e) => e?.message?.includes('has no field `withdrawalRequesteds`'))) {
72
+ errors = await probeSchemaErrors(goldskyUrl, 'transfers', apiKey);
73
+ }
74
+ const schema = isSubgraphSchemaFieldError(errors)
75
+ ? 'old'
76
+ : 'new';
77
+ core_1.CACHE.set(key, schema, { ttl: SCHEMA_TTL_MS });
78
+ return schema;
79
+ }
80
+ catch (e) {
81
+ // Don't cache an inconclusive probe — let the next call retry. Default to
82
+ // 'new' so freshly-deployed vaults keep working when the probe is flaky.
83
+ core_1.Logger.log.warn('resolveSubgraphSchema', `probe failed for ${goldskyUrl}, defaulting to new schema: ${e instanceof Error ? e.message : 'unknown error'}`);
84
+ return 'new';
85
+ }
86
+ }
87
+ //# sourceMappingURL=schema.js.map