augustdigital-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.
- package/LICENSE +21 -0
- package/README.md +349 -0
- package/lib/abis/AddressResolver.d.ts +28 -0
- package/lib/abis/AddressResolver.js +23 -0
- package/lib/abis/ChainlinkV3.d.ts +87 -0
- package/lib/abis/ChainlinkV3.js +117 -0
- package/lib/abis/ERC20.d.ts +168 -0
- package/lib/abis/ERC20.js +226 -0
- package/lib/abis/ERC20_Bytes32.d.ts +139 -0
- package/lib/abis/ERC20_Bytes32.js +196 -0
- package/lib/abis/ERC4626.d.ts +364 -0
- package/lib/abis/ERC4626.js +507 -0
- package/lib/abis/ERC721.d.ts +231 -0
- package/lib/abis/ERC721.js +321 -0
- package/lib/abis/FeeOracle.d.ts +120 -0
- package/lib/abis/FeeOracle.js +162 -0
- package/lib/abis/LendingPool.d.ts +1393 -0
- package/lib/abis/LendingPool.js +1807 -0
- package/lib/abis/LendingPoolV2.d.ts +1413 -0
- package/lib/abis/LendingPoolV2.js +1833 -0
- package/lib/abis/LendingPoolV3.d.ts +1677 -0
- package/lib/abis/LendingPoolV3.js +1160 -0
- package/lib/abis/Loan.d.ts +837 -0
- package/lib/abis/Loan.js +1080 -0
- package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
- package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
- package/lib/abis/Multicall3.d.ts +30 -0
- package/lib/abis/Multicall3.js +97 -0
- package/lib/abis/OFT.d.ts +116 -0
- package/lib/abis/OFT.js +85 -0
- package/lib/abis/PoolAdapter.d.ts +36 -0
- package/lib/abis/PoolAdapter.js +51 -0
- package/lib/abis/RewardDistributor.d.ts +267 -0
- package/lib/abis/RewardDistributor.js +352 -0
- package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
- package/lib/abis/RwaRedeemSubaccount.js +548 -0
- package/lib/abis/SmartAccount.d.ts +17 -0
- package/lib/abis/SmartAccount.js +19 -0
- package/lib/abis/SwapRouter.d.ts +1043 -0
- package/lib/abis/SwapRouter.js +740 -0
- package/lib/abis/TextResolver.d.ts +16 -0
- package/lib/abis/TextResolver.js +16 -0
- package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
- package/lib/abis/TokenizedVaultV2.js +1041 -0
- package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
- package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
- package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
- package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
- package/lib/abis/UniversalResolverResolve.d.ts +69 -0
- package/lib/abis/UniversalResolverResolve.js +35 -0
- package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
- package/lib/abis/UniversalSignatureValidator.js +30 -0
- package/lib/abis/WrapperAdapter.d.ts +71 -0
- package/lib/abis/WrapperAdapter.js +77 -0
- package/lib/abis/index.d.ts +34 -0
- package/lib/abis/index.js +51 -0
- package/lib/adapters/evm/getters.d.ts +19 -0
- package/lib/adapters/evm/getters.js +209 -0
- package/lib/adapters/evm/index.d.ts +353 -0
- package/lib/adapters/evm/index.js +434 -0
- package/lib/adapters/evm/utils.d.ts +8 -0
- package/lib/adapters/evm/utils.js +51 -0
- package/lib/adapters/solana/constants.d.ts +33 -0
- package/lib/adapters/solana/constants.js +52 -0
- package/lib/adapters/solana/getters.d.ts +11 -0
- package/lib/adapters/solana/getters.js +165 -0
- package/lib/adapters/solana/idl/vault-idl.d.ts +272 -0
- package/lib/adapters/solana/idl/vault-idl.js +1084 -0
- package/lib/adapters/solana/index.d.ts +233 -0
- package/lib/adapters/solana/index.js +291 -0
- package/lib/adapters/solana/types.d.ts +67 -0
- package/lib/adapters/solana/types.js +3 -0
- package/lib/adapters/solana/utils.d.ts +141 -0
- package/lib/adapters/solana/utils.js +595 -0
- package/lib/adapters/solana/vault.actions.d.ts +57 -0
- package/lib/adapters/solana/vault.actions.js +379 -0
- package/lib/adapters/stellar/actions.d.ts +28 -0
- package/lib/adapters/stellar/actions.js +77 -0
- package/lib/adapters/stellar/constants.d.ts +43 -0
- package/lib/adapters/stellar/constants.js +53 -0
- package/lib/adapters/stellar/getters.d.ts +68 -0
- package/lib/adapters/stellar/getters.js +290 -0
- package/lib/adapters/stellar/index.d.ts +114 -0
- package/lib/adapters/stellar/index.js +175 -0
- package/lib/adapters/stellar/soroban.d.ts +123 -0
- package/lib/adapters/stellar/soroban.js +613 -0
- package/lib/adapters/stellar/submit.d.ts +34 -0
- package/lib/adapters/stellar/submit.js +149 -0
- package/lib/adapters/stellar/types.d.ts +58 -0
- package/lib/adapters/stellar/types.js +6 -0
- package/lib/adapters/stellar/utils.d.ts +24 -0
- package/lib/adapters/stellar/utils.js +34 -0
- package/lib/adapters/sui/constants.d.ts +14 -0
- package/lib/adapters/sui/constants.js +29 -0
- package/lib/adapters/sui/getters.d.ts +9 -0
- package/lib/adapters/sui/getters.js +60 -0
- package/lib/adapters/sui/index.d.ts +45 -0
- package/lib/adapters/sui/index.js +101 -0
- package/lib/adapters/sui/transformer.d.ts +10 -0
- package/lib/adapters/sui/transformer.js +107 -0
- package/lib/adapters/sui/types.d.ts +66 -0
- package/lib/adapters/sui/types.js +3 -0
- package/lib/adapters/sui/utils.d.ts +10 -0
- package/lib/adapters/sui/utils.js +29 -0
- package/lib/core/analytics/chain-name.d.ts +9 -0
- package/lib/core/analytics/chain-name.js +34 -0
- package/lib/core/analytics/constants.d.ts +5 -0
- package/lib/core/analytics/constants.js +9 -0
- package/lib/core/analytics/env.d.ts +29 -0
- package/lib/core/analytics/env.js +59 -0
- package/lib/core/analytics/index.d.ts +36 -0
- package/lib/core/analytics/index.js +79 -0
- package/lib/core/analytics/instrumentation.d.ts +29 -0
- package/lib/core/analytics/instrumentation.js +277 -0
- package/lib/core/analytics/method-taxonomy.d.ts +19 -0
- package/lib/core/analytics/method-taxonomy.js +128 -0
- package/lib/core/analytics/metrics.d.ts +33 -0
- package/lib/core/analytics/metrics.js +116 -0
- package/lib/core/analytics/sanitize.d.ts +44 -0
- package/lib/core/analytics/sanitize.js +260 -0
- package/lib/core/analytics/sentry-runtime.d.ts +15 -0
- package/lib/core/analytics/sentry-runtime.js +97 -0
- package/lib/core/analytics/sentry.d.ts +67 -0
- package/lib/core/analytics/sentry.js +613 -0
- package/lib/core/analytics/types.d.ts +48 -0
- package/lib/core/analytics/types.js +3 -0
- package/lib/core/analytics/user-identity.d.ts +41 -0
- package/lib/core/analytics/user-identity.js +141 -0
- package/lib/core/analytics/version.d.ts +6 -0
- package/lib/core/analytics/version.js +10 -0
- package/lib/core/attribution.d.ts +111 -0
- package/lib/core/attribution.js +142 -0
- package/lib/core/auth/index.d.ts +1 -0
- package/lib/core/auth/index.js +18 -0
- package/lib/core/auth/verify.d.ts +2 -0
- package/lib/core/auth/verify.js +31 -0
- package/lib/core/base.class.d.ts +152 -0
- package/lib/core/base.class.js +172 -0
- package/lib/core/cache.d.ts +9 -0
- package/lib/core/cache.js +31 -0
- package/lib/core/constants/adapters.d.ts +103 -0
- package/lib/core/constants/adapters.js +180 -0
- package/lib/core/constants/core.d.ts +133 -0
- package/lib/core/constants/core.js +209 -0
- package/lib/core/constants/swap-router.d.ts +150 -0
- package/lib/core/constants/swap-router.js +169 -0
- package/lib/core/constants/vaults.d.ts +93 -0
- package/lib/core/constants/vaults.js +273 -0
- package/lib/core/constants/web3.d.ts +91 -0
- package/lib/core/constants/web3.js +229 -0
- package/lib/core/errors/index.d.ts +114 -0
- package/lib/core/errors/index.js +183 -0
- package/lib/core/fetcher.d.ts +198 -0
- package/lib/core/fetcher.js +903 -0
- package/lib/core/helpers/adapters.d.ts +13 -0
- package/lib/core/helpers/adapters.js +39 -0
- package/lib/core/helpers/chain-address.d.ts +13 -0
- package/lib/core/helpers/chain-address.js +47 -0
- package/lib/core/helpers/chain-error.d.ts +207 -0
- package/lib/core/helpers/chain-error.js +682 -0
- package/lib/core/helpers/chain-support.d.ts +80 -0
- package/lib/core/helpers/chain-support.js +115 -0
- package/lib/core/helpers/core.d.ts +68 -0
- package/lib/core/helpers/core.js +285 -0
- package/lib/core/helpers/explorer-link.d.ts +16 -0
- package/lib/core/helpers/explorer-link.js +26 -0
- package/lib/core/helpers/multicall.d.ts +68 -0
- package/lib/core/helpers/multicall.js +103 -0
- package/lib/core/helpers/revert-decode.d.ts +248 -0
- package/lib/core/helpers/revert-decode.js +515 -0
- package/lib/core/helpers/signer.d.ts +52 -0
- package/lib/core/helpers/signer.js +145 -0
- package/lib/core/helpers/swap-router.d.ts +211 -0
- package/lib/core/helpers/swap-router.js +480 -0
- package/lib/core/helpers/vault-version.d.ts +23 -0
- package/lib/core/helpers/vault-version.js +75 -0
- package/lib/core/helpers/vaults.d.ts +89 -0
- package/lib/core/helpers/vaults.js +235 -0
- package/lib/core/helpers/web3.d.ts +353 -0
- package/lib/core/helpers/web3.js +992 -0
- package/lib/core/index.d.ts +23 -0
- package/lib/core/index.js +40 -0
- package/lib/core/logger/index.d.ts +98 -0
- package/lib/core/logger/index.js +144 -0
- package/lib/core/logger/slack.d.ts +16 -0
- package/lib/core/logger/slack.js +57 -0
- package/lib/core/vault-metadata.d.ts +12 -0
- package/lib/core/vault-metadata.js +42 -0
- package/lib/core/version-check.d.ts +58 -0
- package/lib/core/version-check.js +182 -0
- package/lib/evm/index.d.ts +2 -0
- package/lib/evm/index.js +19 -0
- package/lib/evm/methods/crossChainVault.d.ts +128 -0
- package/lib/evm/methods/crossChainVault.js +853 -0
- package/lib/evm/methods/crossChainVaultRegistry.d.ts +93 -0
- package/lib/evm/methods/crossChainVaultRegistry.js +240 -0
- package/lib/evm/methods/index.d.ts +2 -0
- package/lib/evm/methods/index.js +19 -0
- package/lib/evm/types/crossChain.d.ts +363 -0
- package/lib/evm/types/crossChain.js +20 -0
- package/lib/evm/types/index.d.ts +1 -0
- package/lib/evm/types/index.js +18 -0
- package/lib/index.d.ts +30 -0
- package/lib/index.js +52 -0
- package/lib/main.d.ts +527 -0
- package/lib/main.js +601 -0
- package/lib/modules/api/fetcher.d.ts +82 -0
- package/lib/modules/api/fetcher.js +150 -0
- package/lib/modules/api/index.d.ts +1 -0
- package/lib/modules/api/index.js +6 -0
- package/lib/modules/api/main.d.ts +313 -0
- package/lib/modules/api/main.js +479 -0
- package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
- package/lib/modules/sub-accounts/fetcher.js +120 -0
- package/lib/modules/sub-accounts/index.d.ts +2 -0
- package/lib/modules/sub-accounts/index.js +19 -0
- package/lib/modules/sub-accounts/main.d.ts +243 -0
- package/lib/modules/sub-accounts/main.js +205 -0
- package/lib/modules/sub-accounts/utils.d.ts +106 -0
- package/lib/modules/sub-accounts/utils.js +112 -0
- package/lib/modules/vaults/adapter.helpers.d.ts +64 -0
- package/lib/modules/vaults/adapter.helpers.js +184 -0
- package/lib/modules/vaults/fetcher.d.ts +147 -0
- package/lib/modules/vaults/fetcher.js +368 -0
- package/lib/modules/vaults/getters.d.ts +570 -0
- package/lib/modules/vaults/getters.js +3051 -0
- package/lib/modules/vaults/index.d.ts +20 -0
- package/lib/modules/vaults/index.js +44 -0
- package/lib/modules/vaults/main.d.ts +601 -0
- package/lib/modules/vaults/main.js +1623 -0
- package/lib/modules/vaults/prefetch.d.ts +65 -0
- package/lib/modules/vaults/prefetch.js +120 -0
- package/lib/modules/vaults/read.actions.d.ts +225 -0
- package/lib/modules/vaults/read.actions.js +596 -0
- package/lib/modules/vaults/types.d.ts +71 -0
- package/lib/modules/vaults/types.js +3 -0
- package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
- package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
- package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
- package/lib/modules/vaults/utils/date-utils.js +84 -0
- package/lib/modules/vaults/utils.d.ts +140 -0
- package/lib/modules/vaults/utils.js +799 -0
- package/lib/modules/vaults/write.actions.d.ts +529 -0
- package/lib/modules/vaults/write.actions.js +1749 -0
- package/lib/polyfills.d.ts +1 -0
- package/lib/polyfills.js +12 -0
- package/lib/sdk.d.ts +26721 -0
- package/lib/services/coingecko/fetcher.d.ts +15 -0
- package/lib/services/coingecko/fetcher.js +67 -0
- package/lib/services/coingecko/index.d.ts +2 -0
- package/lib/services/coingecko/index.js +19 -0
- package/lib/services/coingecko/utils.d.ts +1 -0
- package/lib/services/coingecko/utils.js +24 -0
- package/lib/services/debank/fetcher.d.ts +126 -0
- package/lib/services/debank/fetcher.js +47 -0
- package/lib/services/debank/index.d.ts +2 -0
- package/lib/services/debank/index.js +19 -0
- package/lib/services/debank/utils.d.ts +38 -0
- package/lib/services/debank/utils.js +297 -0
- package/lib/services/layerzero/deposits.d.ts +49 -0
- package/lib/services/layerzero/deposits.js +166 -0
- package/lib/services/layerzero/redeems.d.ts +20 -0
- package/lib/services/layerzero/redeems.js +92 -0
- package/lib/services/layerzero/utils.d.ts +9 -0
- package/lib/services/layerzero/utils.js +22 -0
- package/lib/services/octavfi/fetcher.d.ts +9 -0
- package/lib/services/octavfi/fetcher.js +103 -0
- package/lib/services/octavfi/index.d.ts +3 -0
- package/lib/services/octavfi/index.js +20 -0
- package/lib/services/octavfi/types.d.ts +34 -0
- package/lib/services/octavfi/types.js +3 -0
- package/lib/services/octavfi/utils.d.ts +16 -0
- package/lib/services/octavfi/utils.js +212 -0
- package/lib/services/subgraph/fetcher.d.ts +2 -0
- package/lib/services/subgraph/fetcher.js +61 -0
- package/lib/services/subgraph/index.d.ts +2 -0
- package/lib/services/subgraph/index.js +19 -0
- package/lib/services/subgraph/schema.d.ts +45 -0
- package/lib/services/subgraph/schema.js +75 -0
- package/lib/services/subgraph/vaults.d.ts +25 -0
- package/lib/services/subgraph/vaults.js +1106 -0
- package/lib/services/swap-quotes/index.d.ts +105 -0
- package/lib/services/swap-quotes/index.js +77 -0
- package/lib/services/swap-quotes/paraswap.d.ts +51 -0
- package/lib/services/swap-quotes/paraswap.js +138 -0
- package/lib/types/api.d.ts +280 -0
- package/lib/types/api.js +3 -0
- package/lib/types/index.d.ts +12 -0
- package/lib/types/index.js +28 -0
- package/lib/types/points.d.ts +28 -0
- package/lib/types/points.js +3 -0
- package/lib/types/pools.d.ts +144 -0
- package/lib/types/pools.js +3 -0
- package/lib/types/staking.d.ts +28 -0
- package/lib/types/staking.js +3 -0
- package/lib/types/sub-accounts.d.ts +140 -0
- package/lib/types/sub-accounts.js +3 -0
- package/lib/types/subgraph.d.ts +74 -0
- package/lib/types/subgraph.js +3 -0
- package/lib/types/typed-contract.d.ts +102 -0
- package/lib/types/typed-contract.js +3 -0
- package/lib/types/user.d.ts +1 -0
- package/lib/types/user.js +3 -0
- package/lib/types/vaults.d.ts +714 -0
- package/lib/types/vaults.js +24 -0
- package/lib/types/web3.d.ts +51 -0
- package/lib/types/web3.js +14 -0
- package/lib/types/webserver.d.ts +698 -0
- package/lib/types/webserver.js +3 -0
- package/package.json +78 -0
|
@@ -0,0 +1,1106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isOldSubgraphSchema = isOldSubgraphSchema;
|
|
4
|
+
exports.getSubgraphWithdrawRequests = getSubgraphWithdrawRequests;
|
|
5
|
+
exports.getSubgraphWithdrawProccessed = getSubgraphWithdrawProccessed;
|
|
6
|
+
exports.getSubgraphAllWithdrawals = getSubgraphAllWithdrawals;
|
|
7
|
+
exports.getSubgraphUserHistory = getSubgraphUserHistory;
|
|
8
|
+
exports.getSubgraphVaultHistory = getSubgraphVaultHistory;
|
|
9
|
+
exports.getSubgraphUserTransfers = getSubgraphUserTransfers;
|
|
10
|
+
const ethers_1 = require("ethers");
|
|
11
|
+
const slack_1 = require("../../core/logger/slack");
|
|
12
|
+
const fetcher_1 = require("./fetcher");
|
|
13
|
+
const schema_1 = require("./schema");
|
|
14
|
+
const core_1 = require("../../core");
|
|
15
|
+
const fetcher_2 = require("../../modules/vaults/fetcher");
|
|
16
|
+
/**
|
|
17
|
+
* Utils
|
|
18
|
+
*/
|
|
19
|
+
const GOLDSKY_API_KEY = 'cmd0lz6qf35lg01ty7u20aijy';
|
|
20
|
+
// Dedupe window for "Missing Subgraph" alerts (per pool).
|
|
21
|
+
const MISSING_SUBGRAPH_ALERT_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
22
|
+
/**
|
|
23
|
+
* Emit a "Missing Subgraph" Slack alert at most once per pool per TTL.
|
|
24
|
+
*
|
|
25
|
+
* `getDefaultSubgraphUrl` now returns `undefined` for vaults with no metadata or
|
|
26
|
+
* hardcoded subgraph URL, which makes the readers' `if (!goldskyUrl)` branches
|
|
27
|
+
* reachable (previously the fabricated URL was always truthy, so they were dead
|
|
28
|
+
* code). Portfolio/history flows loop over every vault, so alerting on each read
|
|
29
|
+
* would flood the webhook for every metadata-less vault. Deduping per pool
|
|
30
|
+
* surfaces a genuinely-missing subgraph without the flood.
|
|
31
|
+
*
|
|
32
|
+
* This is the durable signal for BOTH ways a vault's subgraph can be broken — no
|
|
33
|
+
* URL configured, and a URL that answers non-200 (a deleted subgraph 404s). The
|
|
34
|
+
* readers deliberately log those per-request at `warn` rather than `error`: at
|
|
35
|
+
* `error` each one became a billed Sentry issue on every portfolio read, which
|
|
36
|
+
* cost over 2M events in 30 days across a handful of vaults. The volume is
|
|
37
|
+
* per-request, but the condition is per-vault, so this alert is where it belongs.
|
|
38
|
+
*
|
|
39
|
+
* @param args.source - Reader function name, for the alert body.
|
|
40
|
+
* @param args.pool - Vault address (used as the dedupe key, lowercased).
|
|
41
|
+
* @param args.chainId - Chain id for the alert context, or a thunk resolving
|
|
42
|
+
* it. Every current caller has the id in scope and passes it directly. The
|
|
43
|
+
* thunk form exists for a caller that would otherwise have to resolve the id
|
|
44
|
+
* eagerly on every non-200 response — it is invoked only after the dedupe
|
|
45
|
+
* gate passes, so a suppressed alert costs nothing. No such caller exists
|
|
46
|
+
* today; if none appears, this union and the deferred branch below can go.
|
|
47
|
+
* @param args.reason - Why the subgraph is unusable. Defaults to the
|
|
48
|
+
* missing-URL case; pass the HTTP status for a URL that resolved but failed.
|
|
49
|
+
* @param args.slackWebookUrl - Optional override webhook URL.
|
|
50
|
+
*/
|
|
51
|
+
function alertMissingSubgraphOnce(args) {
|
|
52
|
+
const key = `missing-subgraph-alert-${args.pool.toLowerCase()}`;
|
|
53
|
+
if (core_1.CACHE.has(key))
|
|
54
|
+
return;
|
|
55
|
+
core_1.CACHE.set(key, true, { ttl: MISSING_SUBGRAPH_ALERT_TTL_MS });
|
|
56
|
+
const send = (chainId) => slack_1.SLACK.error({
|
|
57
|
+
title: 'Missing Subgraph',
|
|
58
|
+
error: `#${args.source}: ${args.reason ?? 'goldsky url is undefined'}`,
|
|
59
|
+
poolAddress: args.pool,
|
|
60
|
+
chainId,
|
|
61
|
+
slackWebookUrl: args.slackWebookUrl || '',
|
|
62
|
+
});
|
|
63
|
+
if (typeof args.chainId === 'number') {
|
|
64
|
+
send(args.chainId);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Deferred id: the dedupe key is already set, so a rejection here would mute
|
|
68
|
+
// this pool for the full TTL without ever alerting. Release the key instead,
|
|
69
|
+
// leaving the next non-200 free to try again.
|
|
70
|
+
void args
|
|
71
|
+
.chainId()
|
|
72
|
+
.then(send, (e) => {
|
|
73
|
+
core_1.CACHE.delete(key);
|
|
74
|
+
core_1.Logger.log.warn('alertMissingSubgraphOnce', `chain id unresolved, alert skipped: ${e}`);
|
|
75
|
+
})
|
|
76
|
+
// `send` itself can reject (SLACK.error does its own fetch). Without this
|
|
77
|
+
// it escapes as an unhandled rejection instead of being contained here.
|
|
78
|
+
.catch((e) => {
|
|
79
|
+
core_1.Logger.log.warn('alertMissingSubgraphOnce', `alert send failed: ${e}`);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* earnAUSD exists on both Ethereum and Monad, so it needs a _monad suffix
|
|
84
|
+
* to distinguish its Monad subgraph from the Ethereum one.
|
|
85
|
+
* Other Monad-native vaults (sausd, supermon, etc.) don't need this.
|
|
86
|
+
*/
|
|
87
|
+
function needsMonadSuffix(chainId, symbol) {
|
|
88
|
+
return chainId === 143 && symbol.toLowerCase() === 'earnausd';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Read the decimals of every distinct deposit asset in a batch of deposit
|
|
92
|
+
* rows, keyed by lowercased token address.
|
|
93
|
+
*
|
|
94
|
+
* Pre-deposit / evm-2 vaults accept multiple deposit assets whose decimals can
|
|
95
|
+
* differ from the vault's own (e.g. RLUSD at 18 deposited into a 6-decimal
|
|
96
|
+
* sentUSD vault). `transformUserHistory` must normalize each deposit against
|
|
97
|
+
* its own asset's decimals rather than the vault's, or an 18-decimal amount
|
|
98
|
+
* normalized at 6 decimals renders ~1e12× too large (a 0.5 deposit shows as
|
|
99
|
+
* "500B"). `getDecimals` is cached and in-flight-deduped, and the distinct-asset
|
|
100
|
+
* set is tiny (typically 1-3), so this is at most a handful of RPC reads.
|
|
101
|
+
*
|
|
102
|
+
* Native-token deposits carry a sentinel `assetIn` — either the zero address or
|
|
103
|
+
* {@link NATIVE_ADDRESS} — that has no on-chain `decimals()`. These are mapped
|
|
104
|
+
* directly to {@link EVM_NATIVE_DECIMALS} (18 on every supported EVM chain)
|
|
105
|
+
* instead of being read. Without this guard `getDecimals(ZeroAddress)` returns
|
|
106
|
+
* `0`, which the caller's `?? decimals` fallback cannot override (0 is not
|
|
107
|
+
* nullish), overstating a native deposit ~1e18×; and `getDecimals(NATIVE_ADDRESS)`
|
|
108
|
+
* reverts, silently dropping to the vault's decimals which may differ.
|
|
109
|
+
*
|
|
110
|
+
* Only successfully-read decimals are entered in the map; a non-native asset
|
|
111
|
+
* whose `decimals()` read fails is omitted so the caller falls back to the
|
|
112
|
+
* vault's decimals. This also lets the vault-decimals read run in parallel with
|
|
113
|
+
* this one (no fallback value is needed up front).
|
|
114
|
+
*
|
|
115
|
+
* @param provider - EVM contract runner used to read `decimals()`.
|
|
116
|
+
* @param deposits - Deposit rows from the subgraph; `assetIn` may be absent.
|
|
117
|
+
* @returns Map of lowercased asset address to decimals (native sentinels and
|
|
118
|
+
* successful reads only).
|
|
119
|
+
*/
|
|
120
|
+
async function buildDepositAssetDecimals(provider, deposits) {
|
|
121
|
+
const map = new Map();
|
|
122
|
+
// Lowercased native-token sentinels: no ERC-20 `decimals()` exists to read.
|
|
123
|
+
const nativeSentinels = new Set([
|
|
124
|
+
ethers_1.ZeroAddress.toLowerCase(),
|
|
125
|
+
core_1.NATIVE_ADDRESS.toLowerCase(),
|
|
126
|
+
]);
|
|
127
|
+
const unique = new Set();
|
|
128
|
+
for (const d of deposits ?? []) {
|
|
129
|
+
if (d?.assetIn)
|
|
130
|
+
unique.add(d.assetIn.toLowerCase());
|
|
131
|
+
}
|
|
132
|
+
await Promise.all([...unique].map(async (addr) => {
|
|
133
|
+
if (nativeSentinels.has(addr)) {
|
|
134
|
+
map.set(addr, core_1.EVM_NATIVE_DECIMALS);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const dec = await (0, core_1.getDecimals)(provider, addr, false);
|
|
138
|
+
if (typeof dec === 'number')
|
|
139
|
+
map.set(addr, dec);
|
|
140
|
+
}));
|
|
141
|
+
return map;
|
|
142
|
+
}
|
|
143
|
+
function transformUserHistory(data, chainId, decimals, poolAddress, assetDecimals) {
|
|
144
|
+
//ok to return dupes even though withdraws will return dupe because we parse out duplicate txn hash on the FE
|
|
145
|
+
return [
|
|
146
|
+
...(data.withdraws?.map((item) => ({
|
|
147
|
+
...item,
|
|
148
|
+
contractId_: item.contractId_ || poolAddress,
|
|
149
|
+
address: item.receiver,
|
|
150
|
+
amount: item.assets,
|
|
151
|
+
chainId: chainId,
|
|
152
|
+
type: 'withdraw-processed',
|
|
153
|
+
transactionHash: item.transactionHash_,
|
|
154
|
+
timestamp: item.timestamp_,
|
|
155
|
+
decimals: decimals,
|
|
156
|
+
isInstant: true,
|
|
157
|
+
})) || []),
|
|
158
|
+
...(data.withdrawalRequesteds?.map((item) => ({
|
|
159
|
+
...item,
|
|
160
|
+
contractId_: item.contractId_ || poolAddress,
|
|
161
|
+
address: item.receiverAddr,
|
|
162
|
+
amount: item?.assets || item?.shares,
|
|
163
|
+
chainId: chainId,
|
|
164
|
+
type: 'withdraw-request',
|
|
165
|
+
transactionHash: item.transactionHash_,
|
|
166
|
+
timestamp: item.timestamp_,
|
|
167
|
+
decimals: decimals,
|
|
168
|
+
})) || []),
|
|
169
|
+
...(data.withdrawalProcesseds?.map((item) => ({
|
|
170
|
+
...item,
|
|
171
|
+
contractId_: item.contractId_ || poolAddress,
|
|
172
|
+
address: item.receiverAddr,
|
|
173
|
+
amount: item.assetsAmount,
|
|
174
|
+
chainId: chainId,
|
|
175
|
+
type: 'withdraw-processed',
|
|
176
|
+
transactionHash: item.transactionHash_,
|
|
177
|
+
timestamp: item.timestamp_,
|
|
178
|
+
decimals: decimals,
|
|
179
|
+
})) || []),
|
|
180
|
+
...(data.deposits?.map((item) => {
|
|
181
|
+
// Pair the decimals to the amount's denomination. `assets` (evm-1) is
|
|
182
|
+
// already in the vault's underlying, so it keeps the vault decimals.
|
|
183
|
+
// Only `amountIn` (evm-2 / pre-deposit) is denominated in `assetIn`,
|
|
184
|
+
// which may differ from the vault (e.g. RLUSD 18 → sentUSD 6) and would
|
|
185
|
+
// otherwise overstate the amount ~1e12×. Using the same source for both
|
|
186
|
+
// avoids a denomination/decimals mismatch, and the truthy `assetIn`
|
|
187
|
+
// guard drops empty-string addresses back to the vault decimals.
|
|
188
|
+
const assetKey = !item?.assets && item.assetIn ? item.assetIn.toLowerCase() : undefined;
|
|
189
|
+
return {
|
|
190
|
+
...item,
|
|
191
|
+
contractId_: item.contractId_ || poolAddress,
|
|
192
|
+
chainId: chainId,
|
|
193
|
+
type: 'deposit',
|
|
194
|
+
address: item?.sender || item?.senderAddr,
|
|
195
|
+
amount: item?.assets || item?.amountIn,
|
|
196
|
+
transactionHash: item.transactionHash_,
|
|
197
|
+
timestamp: item.timestamp_,
|
|
198
|
+
decimals: (assetKey ? assetDecimals?.get(assetKey) : undefined) ?? decimals,
|
|
199
|
+
};
|
|
200
|
+
}) || []),
|
|
201
|
+
];
|
|
202
|
+
}
|
|
203
|
+
function sortUserHistory(data, chainId, decimals, poolAddress, assetDecimals) {
|
|
204
|
+
if (!(data && chainId && decimals))
|
|
205
|
+
return [];
|
|
206
|
+
return transformUserHistory(data, chainId, decimals, poolAddress, assetDecimals).sort((a, b) => Number(a.timestamp_) - Number(b.timestamp_));
|
|
207
|
+
}
|
|
208
|
+
// queries
|
|
209
|
+
const WITHDRAWALS_REQUESTED_QUERY_PROPS = `
|
|
210
|
+
id
|
|
211
|
+
day
|
|
212
|
+
month
|
|
213
|
+
year
|
|
214
|
+
shares
|
|
215
|
+
assets
|
|
216
|
+
receiverAddr
|
|
217
|
+
ownerAddr
|
|
218
|
+
block_number
|
|
219
|
+
timestamp_
|
|
220
|
+
transactionHash_
|
|
221
|
+
contractId_
|
|
222
|
+
`;
|
|
223
|
+
const EVM_V2_WITHDRAWALS_REQUESTED_QUERY_PROPS = `
|
|
224
|
+
id
|
|
225
|
+
shares
|
|
226
|
+
receiverAddr
|
|
227
|
+
holderAddr
|
|
228
|
+
block_number
|
|
229
|
+
timestamp_
|
|
230
|
+
transactionHash_
|
|
231
|
+
contractId_
|
|
232
|
+
`;
|
|
233
|
+
const WITHDRAWALS_QUERY_PROPS = `
|
|
234
|
+
id
|
|
235
|
+
transactionHash_
|
|
236
|
+
timestamp_
|
|
237
|
+
block_number
|
|
238
|
+
contractId_
|
|
239
|
+
assets
|
|
240
|
+
receiver
|
|
241
|
+
sender
|
|
242
|
+
`;
|
|
243
|
+
const EVM_V2_WITHDRAWALS_QUERY_PROPS = `
|
|
244
|
+
id
|
|
245
|
+
transactionHash_
|
|
246
|
+
timestamp_
|
|
247
|
+
block_number
|
|
248
|
+
contractId_
|
|
249
|
+
assets
|
|
250
|
+
receiver
|
|
251
|
+
sender
|
|
252
|
+
shares
|
|
253
|
+
owner
|
|
254
|
+
`;
|
|
255
|
+
const WITHDRAWALS_PROCESSED_QUERY_PROPS = `
|
|
256
|
+
id
|
|
257
|
+
processedOn
|
|
258
|
+
requestedOn
|
|
259
|
+
receiverAddr
|
|
260
|
+
assetsAmount
|
|
261
|
+
block_number
|
|
262
|
+
timestamp_
|
|
263
|
+
contractId_
|
|
264
|
+
transactionHash_
|
|
265
|
+
`;
|
|
266
|
+
const EVM_V2_WITHDRAWALS_PROCESSED_QUERY_PROPS = `
|
|
267
|
+
id
|
|
268
|
+
receiverAddr
|
|
269
|
+
assetsAmount
|
|
270
|
+
block_number
|
|
271
|
+
timestamp_
|
|
272
|
+
contractId_
|
|
273
|
+
transactionHash_
|
|
274
|
+
`;
|
|
275
|
+
const DEPOSIT_QUERY_PROPS = `
|
|
276
|
+
id
|
|
277
|
+
assets
|
|
278
|
+
transactionHash_
|
|
279
|
+
timestamp_
|
|
280
|
+
contractId_
|
|
281
|
+
sender
|
|
282
|
+
shares
|
|
283
|
+
owner
|
|
284
|
+
`;
|
|
285
|
+
const EVM_V2_DEPOSIT_QUERY_PROPS = `
|
|
286
|
+
id
|
|
287
|
+
assetIn
|
|
288
|
+
amountIn
|
|
289
|
+
transactionHash_
|
|
290
|
+
timestamp_
|
|
291
|
+
contractId_
|
|
292
|
+
senderAddr
|
|
293
|
+
receiverAddr
|
|
294
|
+
`;
|
|
295
|
+
// New deployment process uses a different subgraph schema (no trailing underscores).
|
|
296
|
+
// Vaults in SUBGRAPH_VAULT_URLS use the old schema; everything else uses the new schema.
|
|
297
|
+
// GraphQL aliases map new-schema fields to what the SDK expects internally.
|
|
298
|
+
function isOldSubgraphSchema(vaultSymbol) {
|
|
299
|
+
return (vaultSymbol?.toLowerCase() in
|
|
300
|
+
core_1.SUBGRAPH_VAULT_URLS);
|
|
301
|
+
}
|
|
302
|
+
// New schema query props (shared across evm-1 and evm-2 — the new subgraph schema
|
|
303
|
+
// normalized field names, so no per-version variants are needed)
|
|
304
|
+
const NEW_DEPOSIT_QUERY_PROPS = `
|
|
305
|
+
id
|
|
306
|
+
assetIn
|
|
307
|
+
amountIn
|
|
308
|
+
transactionHash_: transactionHash
|
|
309
|
+
timestamp_: blockTimestamp
|
|
310
|
+
senderAddr
|
|
311
|
+
receiverAddr
|
|
312
|
+
`;
|
|
313
|
+
// The `block_number: blockNumber` alias on these new-schema withdrawal prop
|
|
314
|
+
// sets is required, not cosmetic: getWithdrawalRequestsWithStatus prunes by
|
|
315
|
+
// `Number(req.block_number) >= blockCutoff` (per the ISubgraphBase contract).
|
|
316
|
+
// New-schema subgraphs expose the field as `blockNumber`, so without the alias
|
|
317
|
+
// it reads undefined → Number(undefined) is NaN → every request is pruned
|
|
318
|
+
// (AUGUST-6514). Only the REQUESTED set is read today; the processed/withdrawals
|
|
319
|
+
// aliases below are kept for the same type contract so the NaN prune can't recur.
|
|
320
|
+
const NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS = `
|
|
321
|
+
id
|
|
322
|
+
shares
|
|
323
|
+
receiverAddr
|
|
324
|
+
holderAddr
|
|
325
|
+
block_number: blockNumber
|
|
326
|
+
transactionHash_: transactionHash
|
|
327
|
+
timestamp_: blockTimestamp
|
|
328
|
+
`;
|
|
329
|
+
const NEW_WITHDRAWALS_PROCESSED_QUERY_PROPS = `
|
|
330
|
+
id
|
|
331
|
+
receiverAddr
|
|
332
|
+
assetsAmount
|
|
333
|
+
block_number: blockNumber
|
|
334
|
+
transactionHash_: transactionHash
|
|
335
|
+
timestamp_: blockTimestamp
|
|
336
|
+
`;
|
|
337
|
+
const NEW_WITHDRAWALS_QUERY_PROPS = `
|
|
338
|
+
id
|
|
339
|
+
transactionHash_: transactionHash
|
|
340
|
+
timestamp_: blockTimestamp
|
|
341
|
+
block_number: blockNumber
|
|
342
|
+
assets
|
|
343
|
+
receiver
|
|
344
|
+
sender
|
|
345
|
+
shares
|
|
346
|
+
owner
|
|
347
|
+
`;
|
|
348
|
+
// New schema: transfer query props
|
|
349
|
+
const NEW_TRANSFER_QUERY_PROPS = `
|
|
350
|
+
id
|
|
351
|
+
from
|
|
352
|
+
to
|
|
353
|
+
value
|
|
354
|
+
transactionHash_: transactionHash
|
|
355
|
+
timestamp_: blockTimestamp
|
|
356
|
+
block_number: blockNumber
|
|
357
|
+
`;
|
|
358
|
+
const TRANSFER_QUERY_PROPS = `
|
|
359
|
+
id
|
|
360
|
+
from
|
|
361
|
+
to
|
|
362
|
+
value
|
|
363
|
+
transactionHash_
|
|
364
|
+
timestamp_
|
|
365
|
+
block_number
|
|
366
|
+
contractId_
|
|
367
|
+
`;
|
|
368
|
+
/**
|
|
369
|
+
*
|
|
370
|
+
* @param pool
|
|
371
|
+
* @param provider
|
|
372
|
+
* @returns
|
|
373
|
+
*/
|
|
374
|
+
async function getSubgraphWithdrawRequests(pool, provider, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL) {
|
|
375
|
+
// setup
|
|
376
|
+
let vaultSymbol = await (0, core_1.getVaultSymbol)(pool, provider);
|
|
377
|
+
if (vaultSymbol === undefined) {
|
|
378
|
+
core_1.Logger.log.warn('getSubgraphWithdrawRequests', `cannot find vault symbol for pool: ${pool}`);
|
|
379
|
+
return [];
|
|
380
|
+
}
|
|
381
|
+
const networkValue = await provider.provider.getNetwork();
|
|
382
|
+
const network = Number(networkValue.chainId);
|
|
383
|
+
if (needsMonadSuffix(network, vaultSymbol)) {
|
|
384
|
+
vaultSymbol = vaultSymbol.concat('_monad');
|
|
385
|
+
}
|
|
386
|
+
// sanitize
|
|
387
|
+
if (vaultSymbol === 'testWETHTSA') {
|
|
388
|
+
return [];
|
|
389
|
+
}
|
|
390
|
+
const vaultsMetadata = await (0, fetcher_2.fetchVaultMetadata)();
|
|
391
|
+
const { subgraph } = vaultsMetadata?.[vaultSymbol?.toLowerCase()] || {};
|
|
392
|
+
const goldskyUrl = subgraph ||
|
|
393
|
+
core_1.SUBGRAPH_VAULT_URLS[vaultSymbol?.toLowerCase()] ||
|
|
394
|
+
(0, core_1.getDefaultSubgraphUrl)(networkValue.name, vaultSymbol);
|
|
395
|
+
const requests = [];
|
|
396
|
+
if (!goldskyUrl) {
|
|
397
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
398
|
+
core_1.Logger.log.warn('getSubgraphWithdrawRequests', `goldsky url is undefined: ${vaultSymbol}::${pool}`);
|
|
399
|
+
alertMissingSubgraphOnce({
|
|
400
|
+
source: 'getSubgraphWithdrawRequests',
|
|
401
|
+
pool,
|
|
402
|
+
chainId,
|
|
403
|
+
slackWebookUrl,
|
|
404
|
+
});
|
|
405
|
+
return [];
|
|
406
|
+
}
|
|
407
|
+
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(pool))?.[0];
|
|
408
|
+
const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
409
|
+
// Probe the deployed subgraph to learn its actual field schema (cached per
|
|
410
|
+
// URL) instead of guessing from the vault symbol. See resolveSubgraphSchema —
|
|
411
|
+
// the old symbol-map heuristic silently emptied this set for vaults deployed
|
|
412
|
+
// on the old template but absent from SUBGRAPH_VAULT_URLS (AUGUST-6568).
|
|
413
|
+
const useOldSchema = (await (0, schema_1.resolveSubgraphSchema)(goldskyUrl, GOLDSKY_API_KEY)) === 'old';
|
|
414
|
+
const orderByTimestamp = useOldSchema ? 'timestamp_' : 'blockTimestamp';
|
|
415
|
+
const withdrawalRequestedProps = useOldSchema
|
|
416
|
+
? version === 'evm-2'
|
|
417
|
+
? EVM_V2_WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
418
|
+
: WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
419
|
+
: NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS;
|
|
420
|
+
const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, `{
|
|
421
|
+
withdrawalRequesteds(
|
|
422
|
+
first: 1000,
|
|
423
|
+
orderBy: ${orderByTimestamp},
|
|
424
|
+
orderDirection: desc,
|
|
425
|
+
) {
|
|
426
|
+
${withdrawalRequestedProps}
|
|
427
|
+
}
|
|
428
|
+
}`, GOLDSKY_API_KEY);
|
|
429
|
+
if (result.status !== 200) {
|
|
430
|
+
core_1.Logger.log.warn('getSubgraphWithdrawRequests', `${result.statusText}::${result.status}: ${vaultSymbol}::${pool}`);
|
|
431
|
+
alertMissingSubgraphOnce({
|
|
432
|
+
source: 'getSubgraphWithdrawRequests',
|
|
433
|
+
pool,
|
|
434
|
+
// Already resolved at the top of this function — no re-fetch, and the
|
|
435
|
+
// alert fires synchronously.
|
|
436
|
+
chainId: network,
|
|
437
|
+
reason: `subgraph returned ${result.status} ${result.statusText}`,
|
|
438
|
+
slackWebookUrl,
|
|
439
|
+
});
|
|
440
|
+
return [];
|
|
441
|
+
}
|
|
442
|
+
const json = (await result.json());
|
|
443
|
+
requests.push(...(json?.data?.withdrawalRequesteds || []));
|
|
444
|
+
return requests;
|
|
445
|
+
}
|
|
446
|
+
async function getSubgraphWithdrawProccessed(pool, provider, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL) {
|
|
447
|
+
try {
|
|
448
|
+
// setup
|
|
449
|
+
let vaultSymbol = await (0, core_1.getVaultSymbol)(pool, provider);
|
|
450
|
+
if (vaultSymbol === undefined) {
|
|
451
|
+
core_1.Logger.log.warn('getSubgraphWithdrawProccessed', `cannot find vault symbol for pool: ${pool}`);
|
|
452
|
+
return [];
|
|
453
|
+
}
|
|
454
|
+
const networkValue = await provider.provider.getNetwork();
|
|
455
|
+
const network = Number(networkValue.chainId);
|
|
456
|
+
if (needsMonadSuffix(network, vaultSymbol)) {
|
|
457
|
+
vaultSymbol = vaultSymbol.concat('_monad');
|
|
458
|
+
}
|
|
459
|
+
const noWithdrawalProcessed = vaultSymbol === 'agETH';
|
|
460
|
+
// sanitize
|
|
461
|
+
if (vaultSymbol === 'testWETHTSA' || noWithdrawalProcessed) {
|
|
462
|
+
return [];
|
|
463
|
+
}
|
|
464
|
+
const vaultsMetadata = await (0, fetcher_2.fetchVaultMetadata)();
|
|
465
|
+
const { subgraph } = vaultsMetadata?.[vaultSymbol?.toLowerCase()] || {};
|
|
466
|
+
const goldskyUrl = subgraph ||
|
|
467
|
+
core_1.SUBGRAPH_VAULT_URLS[vaultSymbol?.toLowerCase()] ||
|
|
468
|
+
(0, core_1.getDefaultSubgraphUrl)(networkValue.name, vaultSymbol);
|
|
469
|
+
const requests = [];
|
|
470
|
+
if (!goldskyUrl) {
|
|
471
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
472
|
+
core_1.Logger.log.warn('getSubgraphWithdrawProccessed.missing-subgraph-url', `goldsky url is undefined: ${vaultSymbol}::${pool}`, { chainId });
|
|
473
|
+
alertMissingSubgraphOnce({
|
|
474
|
+
source: 'getSubgraphWithdrawProccessed',
|
|
475
|
+
pool,
|
|
476
|
+
chainId,
|
|
477
|
+
slackWebookUrl,
|
|
478
|
+
});
|
|
479
|
+
return [];
|
|
480
|
+
}
|
|
481
|
+
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(pool))?.[0];
|
|
482
|
+
const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
483
|
+
// Probe the deployed subgraph's actual field schema (cached per URL) rather
|
|
484
|
+
// than guessing from the vault symbol — see resolveSubgraphSchema (AUGUST-6568).
|
|
485
|
+
const useOldSchema = (await (0, schema_1.resolveSubgraphSchema)(goldskyUrl, GOLDSKY_API_KEY)) === 'old';
|
|
486
|
+
const orderByTimestamp = useOldSchema ? 'timestamp_' : 'blockTimestamp';
|
|
487
|
+
const withdrawalProcessedProps = useOldSchema
|
|
488
|
+
? version === 'evm-2'
|
|
489
|
+
? EVM_V2_WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
490
|
+
: WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
491
|
+
: NEW_WITHDRAWALS_PROCESSED_QUERY_PROPS;
|
|
492
|
+
const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, `{
|
|
493
|
+
withdrawalProcesseds (
|
|
494
|
+
first: 1000,
|
|
495
|
+
orderBy: ${orderByTimestamp},
|
|
496
|
+
orderDirection: desc,
|
|
497
|
+
) {
|
|
498
|
+
${withdrawalProcessedProps}
|
|
499
|
+
}
|
|
500
|
+
}`, GOLDSKY_API_KEY);
|
|
501
|
+
if (result.status !== 200) {
|
|
502
|
+
core_1.Logger.log.warn('getSubgraphWithdrawProccessed', `${result.statusText}::${result.status}: ${vaultSymbol}::${pool}`);
|
|
503
|
+
alertMissingSubgraphOnce({
|
|
504
|
+
source: 'getSubgraphWithdrawProccessed',
|
|
505
|
+
pool,
|
|
506
|
+
// Already resolved at the top of this function — no re-fetch, and the
|
|
507
|
+
// alert fires synchronously.
|
|
508
|
+
chainId: network,
|
|
509
|
+
reason: `subgraph returned ${result.status} ${result.statusText}`,
|
|
510
|
+
slackWebookUrl,
|
|
511
|
+
});
|
|
512
|
+
return [];
|
|
513
|
+
}
|
|
514
|
+
const json = (await result.json());
|
|
515
|
+
requests.push(...(json?.data?.withdrawalProcesseds || []));
|
|
516
|
+
return requests;
|
|
517
|
+
}
|
|
518
|
+
catch (e) {
|
|
519
|
+
core_1.Logger.log.error('getSubgraphWithdrawProccessed', e, { pool });
|
|
520
|
+
return [];
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
*
|
|
525
|
+
* @param pool
|
|
526
|
+
* @param provider
|
|
527
|
+
* @returns
|
|
528
|
+
*/
|
|
529
|
+
async function getSubgraphAllWithdrawals(pool, provider, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL) {
|
|
530
|
+
let query = '';
|
|
531
|
+
try {
|
|
532
|
+
// setup
|
|
533
|
+
const errorReturnObj = {
|
|
534
|
+
withdrawalRequesteds: [],
|
|
535
|
+
withdrawalProcesseds: [],
|
|
536
|
+
};
|
|
537
|
+
let vaultSymbol = await (0, core_1.getVaultSymbol)(pool, provider);
|
|
538
|
+
if (vaultSymbol === undefined) {
|
|
539
|
+
core_1.Logger.log.warn('getSubgraphAllWithdrawals', `cannot find vault symbol for pool: ${pool}`);
|
|
540
|
+
return errorReturnObj;
|
|
541
|
+
}
|
|
542
|
+
const networkValue = await provider.provider.getNetwork();
|
|
543
|
+
const network = Number(networkValue.chainId);
|
|
544
|
+
if (needsMonadSuffix(network, vaultSymbol)) {
|
|
545
|
+
vaultSymbol = vaultSymbol.concat('_monad');
|
|
546
|
+
}
|
|
547
|
+
const noWithdrawalProcessed = vaultSymbol === 'agETH';
|
|
548
|
+
// sanitize
|
|
549
|
+
if (vaultSymbol === 'testWETHTSA') {
|
|
550
|
+
return errorReturnObj;
|
|
551
|
+
}
|
|
552
|
+
const vaultsMetadata = await (0, fetcher_2.fetchVaultMetadata)();
|
|
553
|
+
const { subgraph } = vaultsMetadata?.[vaultSymbol?.toLowerCase()] || {};
|
|
554
|
+
const goldskyUrl = subgraph ||
|
|
555
|
+
core_1.SUBGRAPH_VAULT_URLS[vaultSymbol?.toLowerCase()] ||
|
|
556
|
+
(0, core_1.getDefaultSubgraphUrl)(networkValue.name, vaultSymbol);
|
|
557
|
+
if (!goldskyUrl) {
|
|
558
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
559
|
+
core_1.Logger.log.warn('getSubgraphAllWithdrawals', `goldsky url is undefined: ${vaultSymbol}::${pool}`);
|
|
560
|
+
alertMissingSubgraphOnce({
|
|
561
|
+
source: 'getSubgraphAllWithdrawals',
|
|
562
|
+
pool,
|
|
563
|
+
chainId,
|
|
564
|
+
slackWebookUrl,
|
|
565
|
+
});
|
|
566
|
+
return errorReturnObj;
|
|
567
|
+
}
|
|
568
|
+
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(pool))?.[0];
|
|
569
|
+
const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
570
|
+
// Probe the deployed subgraph's actual field schema (cached per URL) rather
|
|
571
|
+
// than guessing from the vault symbol — see resolveSubgraphSchema (AUGUST-6568).
|
|
572
|
+
const useOldSchema = (await (0, schema_1.resolveSubgraphSchema)(goldskyUrl, GOLDSKY_API_KEY)) === 'old';
|
|
573
|
+
const orderByTimestamp = useOldSchema ? 'timestamp_' : 'blockTimestamp';
|
|
574
|
+
const withdrawalRequestedProps = useOldSchema
|
|
575
|
+
? version === 'evm-2'
|
|
576
|
+
? EVM_V2_WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
577
|
+
: WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
578
|
+
: NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS;
|
|
579
|
+
const withdrawalProcessedProps = useOldSchema
|
|
580
|
+
? version === 'evm-2'
|
|
581
|
+
? EVM_V2_WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
582
|
+
: WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
583
|
+
: NEW_WITHDRAWALS_PROCESSED_QUERY_PROPS;
|
|
584
|
+
query = `{
|
|
585
|
+
withdrawalRequesteds(
|
|
586
|
+
first: 1000,
|
|
587
|
+
orderBy: ${orderByTimestamp},
|
|
588
|
+
orderDirection: desc,
|
|
589
|
+
) {
|
|
590
|
+
${withdrawalRequestedProps}
|
|
591
|
+
}
|
|
592
|
+
${noWithdrawalProcessed
|
|
593
|
+
? ''
|
|
594
|
+
: `withdrawalProcesseds (
|
|
595
|
+
first: 1000,
|
|
596
|
+
orderBy: ${orderByTimestamp},
|
|
597
|
+
orderDirection: desc,
|
|
598
|
+
) {
|
|
599
|
+
${withdrawalProcessedProps}
|
|
600
|
+
}
|
|
601
|
+
`}
|
|
602
|
+
}`;
|
|
603
|
+
const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, query, GOLDSKY_API_KEY);
|
|
604
|
+
if (result.status !== 200) {
|
|
605
|
+
core_1.Logger.log.warn('getSubgraphAllWithdrawals', `${result.statusText}::${result.status}: ${vaultSymbol}::${pool}`);
|
|
606
|
+
alertMissingSubgraphOnce({
|
|
607
|
+
source: 'getSubgraphAllWithdrawals',
|
|
608
|
+
pool,
|
|
609
|
+
chainId: network,
|
|
610
|
+
reason: `subgraph returned ${result.status} ${result.statusText}`,
|
|
611
|
+
slackWebookUrl,
|
|
612
|
+
});
|
|
613
|
+
return errorReturnObj;
|
|
614
|
+
}
|
|
615
|
+
const json = (await result.json());
|
|
616
|
+
const requests = {
|
|
617
|
+
withdrawalRequesteds: json?.data?.withdrawalRequesteds || [],
|
|
618
|
+
withdrawalProcesseds: json?.data?.withdrawalProcesseds || [],
|
|
619
|
+
};
|
|
620
|
+
return requests;
|
|
621
|
+
}
|
|
622
|
+
catch (e) {
|
|
623
|
+
core_1.Logger.log.error('getSubgraphAllWithdrawals', `${pool}::${e}::${query}`);
|
|
624
|
+
return {
|
|
625
|
+
withdrawalRequesteds: [],
|
|
626
|
+
withdrawalProcesseds: [],
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Fetch a user's deposit/withdraw history for an archived vault from the backend
|
|
632
|
+
* Mongo snapshot (`/upshift/vault_history`) instead of its retired subgraph.
|
|
633
|
+
*
|
|
634
|
+
* Returns the same {@link ISubgraphUserHistoryItem} shape as the subgraph path,
|
|
635
|
+
* so the caller's downstream transform/normalization is unchanged. `amount` is
|
|
636
|
+
* the raw deposited-asset amount (base units); `decimals` is attached so the
|
|
637
|
+
* caller can normalize, mirroring the subgraph path.
|
|
638
|
+
*
|
|
639
|
+
* Pre-deposit vaults accept multiple deposit assets with differing decimals
|
|
640
|
+
* (e.g. USDS at 18, USDC at 6). When the backend supplies `asset_address` per
|
|
641
|
+
* row, it is propagated as {@link ISubgraphUserHistoryItem.assetIn} (and, when
|
|
642
|
+
* present, `asset_decimals` is used for that row's `decimals`) so lifetime PnL
|
|
643
|
+
* resolves each deposit against its own token rather than the vault decimals —
|
|
644
|
+
* without it, an 18-decimal deposit normalized at the vault's 6 decimals
|
|
645
|
+
* inflates the cost basis by ~1e12. This mirrors the subgraph path, whose
|
|
646
|
+
* deposit rows already carry `assetIn`.
|
|
647
|
+
*
|
|
648
|
+
* Side effects: one RPC read (`getDecimals`) and one HTTP GET to the public API.
|
|
649
|
+
*
|
|
650
|
+
* @param user - The wallet whose history to fetch.
|
|
651
|
+
* @param provider - Contract runner, used to read the vault's decimals.
|
|
652
|
+
* @param pool - The (archived) vault contract address.
|
|
653
|
+
* @returns The user's deposits and settled withdrawals. Empty on a non-200
|
|
654
|
+
* response.
|
|
655
|
+
*/
|
|
656
|
+
async function getArchivedVaultUserHistory(user, provider, pool) {
|
|
657
|
+
const decimals = await (0, core_1.getDecimals)(provider, pool);
|
|
658
|
+
const response = await (0, core_1.fetchAugustPublic)(core_1.WEBSERVER_ENDPOINTS.public.tokenizedVault.userHistory(pool, user));
|
|
659
|
+
if (response.status !== 200) {
|
|
660
|
+
core_1.Logger.log.error('getArchivedVaultUserHistory', `non-200 from vault_history for ${pool}: ${response.status}`);
|
|
661
|
+
return [];
|
|
662
|
+
}
|
|
663
|
+
const rows = (await response.json());
|
|
664
|
+
// The backend already stores final ISubgraphUserHistoryItem.type values, so
|
|
665
|
+
// no translation is needed. Two row-level guards before mapping, since both
|
|
666
|
+
// bad shapes propagate destructively downstream:
|
|
667
|
+
// - amount_raw must be a non-negative integer: the caller does
|
|
668
|
+
// BigInt(amount) outside a try/catch, and one bad row would throw and
|
|
669
|
+
// wipe the user's entire (all-vault) history.
|
|
670
|
+
// - timestamp must parse to a real time: a malformed value makes getTime()
|
|
671
|
+
// return NaN, which stringifies to "NaN" and then sorts/normalizes
|
|
672
|
+
// incorrectly downstream. Drop the row rather than emit a "NaN" stamp.
|
|
673
|
+
return (rows
|
|
674
|
+
.filter((row) => /^\d+$/.test(row.amount_raw) &&
|
|
675
|
+
!Number.isNaN(new Date(row.timestamp).getTime()))
|
|
676
|
+
.map((row) => ({
|
|
677
|
+
id: row.transaction_hash,
|
|
678
|
+
contractId_: pool,
|
|
679
|
+
timestamp_: String(Math.floor(new Date(row.timestamp).getTime() / 1000)),
|
|
680
|
+
transactionHash_: row.transaction_hash,
|
|
681
|
+
block_number: row.block_number != null ? String(row.block_number) : '0',
|
|
682
|
+
address: row.wallet,
|
|
683
|
+
amount: row.amount_raw,
|
|
684
|
+
type: row.type,
|
|
685
|
+
// Per-asset decimals when known, else the vault's. PnL re-resolves
|
|
686
|
+
// decimals from `assetIn` anyway; this keeps display/normalization
|
|
687
|
+
// correct for any consumer that reads the row's `decimals` directly.
|
|
688
|
+
decimals: row.asset_decimals ?? decimals,
|
|
689
|
+
// Carry the deposit asset through so mixed-decimal deposits normalize
|
|
690
|
+
// against their own token, not the vault's. Omitted when unknown.
|
|
691
|
+
...(row.asset_address ? { assetIn: row.asset_address } : {}),
|
|
692
|
+
}))
|
|
693
|
+
// Match the subgraph path's ordering contract: sortUserHistory sorts
|
|
694
|
+
// ascending by unix timestamp_, and downstream consumers rely on that
|
|
695
|
+
// chronology. The backend returns rows in arbitrary order, so re-sort here.
|
|
696
|
+
.sort((a, b) => Number(a.timestamp_) - Number(b.timestamp_)));
|
|
697
|
+
}
|
|
698
|
+
async function getSubgraphUserHistory(user, provider, pool, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL) {
|
|
699
|
+
try {
|
|
700
|
+
// This path is EVM-only: it reads chain id and network from an EVM
|
|
701
|
+
// JsonRpcProvider (eth_chainId / getNetwork) and queries an EVM subgraph.
|
|
702
|
+
// A non-EVM (Solana / Stellar) vault address routed here would call
|
|
703
|
+
// eth_chainId against a Solana/Stellar RPC and fail with a 400
|
|
704
|
+
// ("eth_chainId is not available on SOLANA_MAINNET"). Bail early so non-EVM
|
|
705
|
+
// vaults are simply skipped rather than throwing on every history fetch.
|
|
706
|
+
if (!(0, ethers_1.isAddress)(pool)) {
|
|
707
|
+
return [];
|
|
708
|
+
}
|
|
709
|
+
// Archived vaults: serve history from the backend Mongo snapshot instead of
|
|
710
|
+
// the (retired) subgraph. The archived set is fetched from the backend (the
|
|
711
|
+
// routing source of truth) so a vault is only rerouted once its history is
|
|
712
|
+
// backfilled. Same return shape keeps downstream unchanged.
|
|
713
|
+
const archivedVaults = await (0, fetcher_2.fetchArchivedVaults)();
|
|
714
|
+
if (archivedVaults.has(pool.toLowerCase())) {
|
|
715
|
+
return await getArchivedVaultUserHistory(user, provider, pool);
|
|
716
|
+
}
|
|
717
|
+
// setup
|
|
718
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
719
|
+
const requests = [];
|
|
720
|
+
let vaultSymbol = await (0, core_1.getVaultSymbol)(pool, provider);
|
|
721
|
+
if (vaultSymbol === undefined) {
|
|
722
|
+
core_1.Logger.log.warn('getSubgraphUserHistory', `cannot find vault symbol for pool: ${pool}`);
|
|
723
|
+
return requests;
|
|
724
|
+
}
|
|
725
|
+
const networkValue = await provider.provider.getNetwork();
|
|
726
|
+
const network = Number(networkValue.chainId);
|
|
727
|
+
if (needsMonadSuffix(network, vaultSymbol)) {
|
|
728
|
+
vaultSymbol = vaultSymbol.concat('_monad');
|
|
729
|
+
}
|
|
730
|
+
const noWithdrawalProcessed = vaultSymbol === 'agETH';
|
|
731
|
+
// sanitize
|
|
732
|
+
if (vaultSymbol === 'testWETHTSA') {
|
|
733
|
+
return requests;
|
|
734
|
+
}
|
|
735
|
+
const vaultsMetadata = await (0, fetcher_2.fetchVaultMetadata)();
|
|
736
|
+
const { subgraph } = vaultsMetadata?.[vaultSymbol?.toLowerCase()] || {};
|
|
737
|
+
const goldskyUrl = subgraph ||
|
|
738
|
+
core_1.SUBGRAPH_VAULT_URLS[vaultSymbol?.toLowerCase()] ||
|
|
739
|
+
(0, core_1.getDefaultSubgraphUrl)(networkValue.name, vaultSymbol);
|
|
740
|
+
if (!goldskyUrl) {
|
|
741
|
+
core_1.Logger.log.warn('getSubgraphUserHistory', `goldsky url is undefined: ${vaultSymbol}::${pool}`);
|
|
742
|
+
alertMissingSubgraphOnce({
|
|
743
|
+
source: 'getSubgraphUserHistory',
|
|
744
|
+
pool,
|
|
745
|
+
chainId,
|
|
746
|
+
slackWebookUrl,
|
|
747
|
+
});
|
|
748
|
+
return requests;
|
|
749
|
+
}
|
|
750
|
+
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(pool))?.[0];
|
|
751
|
+
const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
752
|
+
// Probe the deployed subgraph's actual field schema (cached per URL) rather
|
|
753
|
+
// than guessing from the vault symbol — see resolveSubgraphSchema (AUGUST-6568).
|
|
754
|
+
const useOldSchema = (await (0, schema_1.resolveSubgraphSchema)(goldskyUrl, GOLDSKY_API_KEY)) === 'old';
|
|
755
|
+
const orderByTimestamp = useOldSchema ? 'timestamp_' : 'blockTimestamp';
|
|
756
|
+
const depositProps = useOldSchema
|
|
757
|
+
? version === 'evm-2'
|
|
758
|
+
? EVM_V2_DEPOSIT_QUERY_PROPS
|
|
759
|
+
: DEPOSIT_QUERY_PROPS
|
|
760
|
+
: NEW_DEPOSIT_QUERY_PROPS;
|
|
761
|
+
const withdrawProps = useOldSchema
|
|
762
|
+
? version === 'evm-2'
|
|
763
|
+
? EVM_V2_WITHDRAWALS_QUERY_PROPS
|
|
764
|
+
: WITHDRAWALS_QUERY_PROPS
|
|
765
|
+
: NEW_WITHDRAWALS_QUERY_PROPS;
|
|
766
|
+
const withdrawalRequestedProps = useOldSchema
|
|
767
|
+
? version === 'evm-2'
|
|
768
|
+
? EVM_V2_WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
769
|
+
: WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
770
|
+
: NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS;
|
|
771
|
+
const withdrawalProcessedProps = useOldSchema
|
|
772
|
+
? version === 'evm-2'
|
|
773
|
+
? EVM_V2_WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
774
|
+
: WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
775
|
+
: NEW_WITHDRAWALS_PROCESSED_QUERY_PROPS;
|
|
776
|
+
const depositQuery = version === 'evm-2'
|
|
777
|
+
? `deposits (
|
|
778
|
+
first: 1000,
|
|
779
|
+
orderBy: ${orderByTimestamp},
|
|
780
|
+
orderDirection: desc,
|
|
781
|
+
where: { receiverAddr: "${user?.toLowerCase()}" }
|
|
782
|
+
) {
|
|
783
|
+
${depositProps}
|
|
784
|
+
}
|
|
785
|
+
`
|
|
786
|
+
: `deposits (
|
|
787
|
+
first: 1000,
|
|
788
|
+
orderBy: ${orderByTimestamp},
|
|
789
|
+
orderDirection: desc,
|
|
790
|
+
where: { owner: "${user?.toLowerCase()}" }
|
|
791
|
+
) {
|
|
792
|
+
${depositProps}
|
|
793
|
+
}`;
|
|
794
|
+
const fullRequest = `{
|
|
795
|
+
withdraws (
|
|
796
|
+
first: 1000,
|
|
797
|
+
orderBy: ${orderByTimestamp},
|
|
798
|
+
orderDirection: desc,
|
|
799
|
+
where: { receiver: "${user?.toLowerCase()}" }
|
|
800
|
+
) {
|
|
801
|
+
${withdrawProps}
|
|
802
|
+
}
|
|
803
|
+
withdrawalRequesteds (
|
|
804
|
+
first: 1000,
|
|
805
|
+
orderBy: ${orderByTimestamp},
|
|
806
|
+
orderDirection: desc,
|
|
807
|
+
where: { receiverAddr: "${user?.toLowerCase()}" }
|
|
808
|
+
) {
|
|
809
|
+
${withdrawalRequestedProps}
|
|
810
|
+
}
|
|
811
|
+
${noWithdrawalProcessed
|
|
812
|
+
? ''
|
|
813
|
+
: `withdrawalProcesseds (
|
|
814
|
+
first: 1000,
|
|
815
|
+
orderBy: ${orderByTimestamp},
|
|
816
|
+
orderDirection: desc,
|
|
817
|
+
where: { receiverAddr: "${user?.toLowerCase()}" }
|
|
818
|
+
) {
|
|
819
|
+
${withdrawalProcessedProps}
|
|
820
|
+
}
|
|
821
|
+
`}
|
|
822
|
+
${depositQuery}
|
|
823
|
+
}`;
|
|
824
|
+
const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, fullRequest, GOLDSKY_API_KEY);
|
|
825
|
+
if (result.status !== 200) {
|
|
826
|
+
core_1.Logger.log.warn('getSubgraphUserHistory', `${result.statusText}::${result.status}: ${vaultSymbol}::${pool}`);
|
|
827
|
+
alertMissingSubgraphOnce({
|
|
828
|
+
source: 'getSubgraphUserHistory',
|
|
829
|
+
pool,
|
|
830
|
+
chainId,
|
|
831
|
+
reason: `subgraph returned ${result.status} ${result.statusText}`,
|
|
832
|
+
slackWebookUrl,
|
|
833
|
+
});
|
|
834
|
+
return requests;
|
|
835
|
+
}
|
|
836
|
+
const json = (await result.json());
|
|
837
|
+
// Format data — vault decimals and per-asset decimals are independent reads.
|
|
838
|
+
const [decimals, assetDecimals] = await Promise.all([
|
|
839
|
+
(0, core_1.getDecimals)(provider, pool),
|
|
840
|
+
buildDepositAssetDecimals(provider, json.data?.deposits),
|
|
841
|
+
]);
|
|
842
|
+
const formattedRequests = sortUserHistory(json.data, chainId, decimals, pool, assetDecimals);
|
|
843
|
+
return formattedRequests;
|
|
844
|
+
}
|
|
845
|
+
catch (e) {
|
|
846
|
+
core_1.Logger.log.error('getSubgraphUserHistory', `${pool}::${e}`);
|
|
847
|
+
return [];
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
async function getSubgraphVaultHistory(provider, pool, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL, opts = {}) {
|
|
851
|
+
try {
|
|
852
|
+
// setup
|
|
853
|
+
const requests = [];
|
|
854
|
+
let vaultSymbol = await (0, core_1.getVaultSymbol)(pool, provider);
|
|
855
|
+
if (vaultSymbol === undefined) {
|
|
856
|
+
core_1.Logger.log.warn('getSubgraphVaultHistory', `cannot find vault symbol for pool: ${pool}`);
|
|
857
|
+
return requests;
|
|
858
|
+
}
|
|
859
|
+
const networkValue = await provider.provider.getNetwork();
|
|
860
|
+
const network = Number(networkValue.chainId);
|
|
861
|
+
if (needsMonadSuffix(network, vaultSymbol)) {
|
|
862
|
+
vaultSymbol = vaultSymbol.concat('_monad');
|
|
863
|
+
} // sanitize
|
|
864
|
+
if (vaultSymbol === 'testWETHTSA') {
|
|
865
|
+
return requests;
|
|
866
|
+
}
|
|
867
|
+
const vaultsMetadata = await (0, fetcher_2.fetchVaultMetadata)();
|
|
868
|
+
const { subgraph } = vaultsMetadata?.[vaultSymbol?.toLowerCase()] || {};
|
|
869
|
+
const goldskyUrl = subgraph ||
|
|
870
|
+
core_1.SUBGRAPH_VAULT_URLS[vaultSymbol?.toLowerCase()] ||
|
|
871
|
+
(0, core_1.getDefaultSubgraphUrl)(networkValue.name, vaultSymbol);
|
|
872
|
+
if (!goldskyUrl) {
|
|
873
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
874
|
+
core_1.Logger.log.warn('getSubgraphVaultHistory', `goldsky url is undefined: ${vaultSymbol}::${pool}`);
|
|
875
|
+
alertMissingSubgraphOnce({
|
|
876
|
+
source: 'getSubgraphVaultHistory',
|
|
877
|
+
pool,
|
|
878
|
+
chainId,
|
|
879
|
+
slackWebookUrl,
|
|
880
|
+
});
|
|
881
|
+
return requests;
|
|
882
|
+
}
|
|
883
|
+
const tokenizedVault = (await (0, core_1.fetchTokenizedVault)(pool))?.[0];
|
|
884
|
+
const version = (0, core_1.getVaultVersionV2)(tokenizedVault);
|
|
885
|
+
// Probe the deployed subgraph's actual field schema (cached per URL) rather
|
|
886
|
+
// than guessing from the vault symbol — see resolveSubgraphSchema (AUGUST-6568).
|
|
887
|
+
const useOldSchema = (await (0, schema_1.resolveSubgraphSchema)(goldskyUrl, GOLDSKY_API_KEY)) === 'old';
|
|
888
|
+
const orderByTimestamp = useOldSchema ? 'timestamp_' : 'blockTimestamp';
|
|
889
|
+
const withdrawProps = useOldSchema
|
|
890
|
+
? version === 'evm-2'
|
|
891
|
+
? EVM_V2_WITHDRAWALS_QUERY_PROPS
|
|
892
|
+
: WITHDRAWALS_QUERY_PROPS
|
|
893
|
+
: NEW_WITHDRAWALS_QUERY_PROPS;
|
|
894
|
+
const withdrawalRequestedProps = useOldSchema
|
|
895
|
+
? version === 'evm-2'
|
|
896
|
+
? EVM_V2_WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
897
|
+
: WITHDRAWALS_REQUESTED_QUERY_PROPS
|
|
898
|
+
: NEW_WITHDRAWALS_REQUESTED_QUERY_PROPS;
|
|
899
|
+
const withdrawalProcessedProps = useOldSchema
|
|
900
|
+
? version === 'evm-2'
|
|
901
|
+
? EVM_V2_WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
902
|
+
: WITHDRAWALS_PROCESSED_QUERY_PROPS
|
|
903
|
+
: NEW_WITHDRAWALS_PROCESSED_QUERY_PROPS;
|
|
904
|
+
const depositProps = useOldSchema
|
|
905
|
+
? version === 'evm-2'
|
|
906
|
+
? EVM_V2_DEPOSIT_QUERY_PROPS
|
|
907
|
+
: DEPOSIT_QUERY_PROPS
|
|
908
|
+
: NEW_DEPOSIT_QUERY_PROPS;
|
|
909
|
+
// Each of the four event entities is capped at 1000 rows per request, so
|
|
910
|
+
// a busy vault would silently truncate. Page all four in lockstep on a
|
|
911
|
+
// shared `skip` cursor (rows are ordered newest-first) and keep going while
|
|
912
|
+
// any entity returned a full page. When `sinceTs` is set we can stop early:
|
|
913
|
+
// once an entity's oldest row in the page predates the window, no later
|
|
914
|
+
// page can contain in-window rows for it.
|
|
915
|
+
const PAGE_SIZE = 1000;
|
|
916
|
+
const accumulated = {
|
|
917
|
+
withdraws: [],
|
|
918
|
+
withdrawalRequesteds: [],
|
|
919
|
+
withdrawalProcesseds: [],
|
|
920
|
+
deposits: [],
|
|
921
|
+
};
|
|
922
|
+
let skip = 0;
|
|
923
|
+
for (;;) {
|
|
924
|
+
const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, `{
|
|
925
|
+
withdraws (
|
|
926
|
+
first: ${PAGE_SIZE},
|
|
927
|
+
skip: ${skip},
|
|
928
|
+
orderBy: ${orderByTimestamp},
|
|
929
|
+
orderDirection: desc,
|
|
930
|
+
) {
|
|
931
|
+
${withdrawProps}
|
|
932
|
+
}
|
|
933
|
+
withdrawalRequesteds (
|
|
934
|
+
first: ${PAGE_SIZE},
|
|
935
|
+
skip: ${skip},
|
|
936
|
+
orderBy: ${orderByTimestamp},
|
|
937
|
+
orderDirection: desc,
|
|
938
|
+
) {
|
|
939
|
+
${withdrawalRequestedProps}
|
|
940
|
+
}
|
|
941
|
+
withdrawalProcesseds (
|
|
942
|
+
first: ${PAGE_SIZE},
|
|
943
|
+
skip: ${skip},
|
|
944
|
+
orderBy: ${orderByTimestamp},
|
|
945
|
+
orderDirection: desc,
|
|
946
|
+
) {
|
|
947
|
+
${withdrawalProcessedProps}
|
|
948
|
+
}
|
|
949
|
+
deposits (
|
|
950
|
+
first: ${PAGE_SIZE},
|
|
951
|
+
skip: ${skip},
|
|
952
|
+
orderBy: ${orderByTimestamp},
|
|
953
|
+
orderDirection: desc,
|
|
954
|
+
) {
|
|
955
|
+
${depositProps}
|
|
956
|
+
}
|
|
957
|
+
}`, GOLDSKY_API_KEY);
|
|
958
|
+
if (result.status !== 200) {
|
|
959
|
+
core_1.Logger.log.warn('getSubgraphVaultHistory', `${result.statusText}::${result.status}: ${vaultSymbol}::${pool}`, { skip });
|
|
960
|
+
alertMissingSubgraphOnce({
|
|
961
|
+
source: 'getSubgraphVaultHistory',
|
|
962
|
+
pool,
|
|
963
|
+
chainId: network,
|
|
964
|
+
reason: `subgraph returned ${result.status} ${result.statusText}`,
|
|
965
|
+
slackWebookUrl,
|
|
966
|
+
});
|
|
967
|
+
// First page failed → nothing to return. A later page failing still
|
|
968
|
+
// yields whatever earlier pages accumulated.
|
|
969
|
+
if (skip === 0)
|
|
970
|
+
return requests;
|
|
971
|
+
break;
|
|
972
|
+
}
|
|
973
|
+
const json = (await result.json());
|
|
974
|
+
const page = json.data;
|
|
975
|
+
accumulated.withdraws.push(...(page?.withdraws ?? []));
|
|
976
|
+
accumulated.withdrawalRequesteds.push(...(page?.withdrawalRequesteds ?? []));
|
|
977
|
+
accumulated.withdrawalProcesseds.push(...(page?.withdrawalProcesseds ?? []));
|
|
978
|
+
accumulated.deposits.push(...(page?.deposits ?? []));
|
|
979
|
+
const entities = [
|
|
980
|
+
page?.withdraws,
|
|
981
|
+
page?.withdrawalRequesteds,
|
|
982
|
+
page?.withdrawalProcesseds,
|
|
983
|
+
page?.deposits,
|
|
984
|
+
];
|
|
985
|
+
const needMore = entities.some((rows) => {
|
|
986
|
+
if ((rows?.length ?? 0) < PAGE_SIZE)
|
|
987
|
+
return false;
|
|
988
|
+
if (opts.sinceTs === undefined)
|
|
989
|
+
return true;
|
|
990
|
+
const oldest = Number(rows?.[rows.length - 1]?.timestamp_);
|
|
991
|
+
return !Number.isFinite(oldest) || oldest >= opts.sinceTs;
|
|
992
|
+
});
|
|
993
|
+
if (!needMore)
|
|
994
|
+
break;
|
|
995
|
+
skip += PAGE_SIZE;
|
|
996
|
+
}
|
|
997
|
+
// Format data — vault decimals and per-asset decimals are independent reads.
|
|
998
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
999
|
+
const [decimals, assetDecimals] = await Promise.all([
|
|
1000
|
+
(0, core_1.getDecimals)(provider, pool),
|
|
1001
|
+
buildDepositAssetDecimals(provider, accumulated?.deposits),
|
|
1002
|
+
]);
|
|
1003
|
+
const formattedRequests = sortUserHistory(accumulated, chainId, decimals, pool, assetDecimals);
|
|
1004
|
+
return formattedRequests;
|
|
1005
|
+
}
|
|
1006
|
+
catch (e) {
|
|
1007
|
+
core_1.Logger.log.error('getSubgraphVaultHistory', e, { pool });
|
|
1008
|
+
return [];
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
async function getSubgraphUserTransfers(user, provider, pool, slackWebookUrl = slack_1.DEFAULT_SLACK_WEBHOOK_URL) {
|
|
1012
|
+
try {
|
|
1013
|
+
// setup
|
|
1014
|
+
let amountOfTransfers = 0;
|
|
1015
|
+
let userTransfers = [];
|
|
1016
|
+
let hasNoData = false;
|
|
1017
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
1018
|
+
const walletAddress = user.toLocaleLowerCase();
|
|
1019
|
+
const rewardDistributorAddresses = (0, core_1.REWARD_DISTRIBUTOR_ADDRESS)(chainId).filter((addr) => addr !== '0x0000000000000000000000000000000000000000');
|
|
1020
|
+
let vaultSymbol = await (0, core_1.getVaultSymbol)(pool, provider);
|
|
1021
|
+
if (vaultSymbol === undefined) {
|
|
1022
|
+
core_1.Logger.log.warn('getSubgraphUserTransfers', `cannot find vault symbol for pool: ${pool}`);
|
|
1023
|
+
return userTransfers;
|
|
1024
|
+
}
|
|
1025
|
+
const networkValue = await provider.provider.getNetwork();
|
|
1026
|
+
const network = Number(networkValue.chainId);
|
|
1027
|
+
if (needsMonadSuffix(network, vaultSymbol)) {
|
|
1028
|
+
vaultSymbol = vaultSymbol.concat('_monad');
|
|
1029
|
+
} // sanitize
|
|
1030
|
+
if (vaultSymbol === 'testWETHTSA') {
|
|
1031
|
+
return userTransfers;
|
|
1032
|
+
}
|
|
1033
|
+
const vaultsMetadata = await (0, fetcher_2.fetchVaultMetadata)();
|
|
1034
|
+
const { subgraph } = vaultsMetadata?.[vaultSymbol?.toLowerCase()] || {};
|
|
1035
|
+
const goldskyUrl = subgraph ||
|
|
1036
|
+
core_1.SUBGRAPH_VAULT_URLS[vaultSymbol?.toLowerCase()] ||
|
|
1037
|
+
(0, core_1.getDefaultSubgraphUrl)(networkValue.name, vaultSymbol);
|
|
1038
|
+
if (!goldskyUrl) {
|
|
1039
|
+
const chainId = await (0, core_1.getChainId)(provider);
|
|
1040
|
+
core_1.Logger.log.warn('getSubgraphUserTransfers', `goldsky url is undefined: ${vaultSymbol}::${pool}`);
|
|
1041
|
+
alertMissingSubgraphOnce({
|
|
1042
|
+
source: 'getSubgraphUserTransfers',
|
|
1043
|
+
pool,
|
|
1044
|
+
chainId,
|
|
1045
|
+
slackWebookUrl,
|
|
1046
|
+
});
|
|
1047
|
+
return userTransfers;
|
|
1048
|
+
}
|
|
1049
|
+
// Probe the deployed subgraph's actual field schema (cached per URL) rather
|
|
1050
|
+
// than guessing from the vault symbol — see resolveSubgraphSchema (AUGUST-6568).
|
|
1051
|
+
const useOldSchema = (await (0, schema_1.resolveSubgraphSchema)(goldskyUrl, GOLDSKY_API_KEY)) === 'old';
|
|
1052
|
+
const orderByTimestamp = useOldSchema ? 'timestamp_' : 'blockTimestamp';
|
|
1053
|
+
const transferProps = useOldSchema
|
|
1054
|
+
? TRANSFER_QUERY_PROPS
|
|
1055
|
+
: NEW_TRANSFER_QUERY_PROPS;
|
|
1056
|
+
do {
|
|
1057
|
+
// get all the transfers, includes redeem requests and deposits, excludes stake and withdraw events
|
|
1058
|
+
const where = `
|
|
1059
|
+
where: {
|
|
1060
|
+
and: [
|
|
1061
|
+
{
|
|
1062
|
+
or: [
|
|
1063
|
+
{from: "${walletAddress}"},
|
|
1064
|
+
{to: "${walletAddress}"}
|
|
1065
|
+
]
|
|
1066
|
+
},
|
|
1067
|
+
${rewardDistributorAddresses.length
|
|
1068
|
+
? `
|
|
1069
|
+
{
|
|
1070
|
+
from_not_in: [
|
|
1071
|
+
${rewardDistributorAddresses.map((addr) => `"${addr.toLocaleLowerCase()}"`).join(', ')}
|
|
1072
|
+
],
|
|
1073
|
+
to_not_in: [${rewardDistributorAddresses.map((addr) => `"${addr.toLocaleLowerCase()}"`).join(', ')}]
|
|
1074
|
+
}
|
|
1075
|
+
`
|
|
1076
|
+
: ''}
|
|
1077
|
+
]
|
|
1078
|
+
},
|
|
1079
|
+
`;
|
|
1080
|
+
if (!pool) {
|
|
1081
|
+
throw new Error('Pool address is required for HyperEVM');
|
|
1082
|
+
}
|
|
1083
|
+
const result = await (0, fetcher_1.fetchSubgraph)(goldskyUrl, `{
|
|
1084
|
+
transfers(
|
|
1085
|
+
first: 1000, skip: ${amountOfTransfers},
|
|
1086
|
+
${where}
|
|
1087
|
+
orderBy: ${orderByTimestamp}, orderDirection: asc
|
|
1088
|
+
) {
|
|
1089
|
+
${transferProps}
|
|
1090
|
+
}
|
|
1091
|
+
}`, GOLDSKY_API_KEY);
|
|
1092
|
+
const json = (await result.json());
|
|
1093
|
+
const { data } = json;
|
|
1094
|
+
userTransfers = [...userTransfers, ...(data?.transfers || [])];
|
|
1095
|
+
amountOfTransfers += data?.transfers?.length || 0;
|
|
1096
|
+
hasNoData = !data?.transfers?.length;
|
|
1097
|
+
} while ((amountOfTransfers === 0 || amountOfTransfers % 1000 === 0) &&
|
|
1098
|
+
!hasNoData);
|
|
1099
|
+
return userTransfers;
|
|
1100
|
+
}
|
|
1101
|
+
catch (e) {
|
|
1102
|
+
core_1.Logger.log.error('getSubgraphUserTransfers', e, { pool });
|
|
1103
|
+
return [];
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
//# sourceMappingURL=vaults.js.map
|