@gearbox-protocol/sdk 15.1.0-next.11 → 15.1.0-next.12

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 (54) hide show
  1. package/dist/cjs/dev/mode-parity/compareOpportunities.js +105 -0
  2. package/dist/cjs/dev/{comparePositions.js → mode-parity/comparePositions.js} +23 -46
  3. package/dist/cjs/dev/mode-parity/compareRules.js +93 -0
  4. package/dist/cjs/dev/{fieldDiff.js → mode-parity/fieldDiff.js} +49 -2
  5. package/dist/cjs/dev/mode-parity/scriptUtils.js +131 -0
  6. package/dist/cjs/model/compare.schema.js +33 -0
  7. package/dist/cjs/model/curators.schema.js +2 -1
  8. package/dist/cjs/model/index.js +5 -0
  9. package/dist/cjs/model/opportunities.schema.js +13 -12
  10. package/dist/cjs/model/positions.schema.js +15 -14
  11. package/dist/cjs/model/primitives.schema.js +2 -1
  12. package/dist/esm/common-utils/index.js +3 -3
  13. package/dist/esm/common-utils/utils/index.js +1 -1
  14. package/dist/esm/dev/AccountOpener.js +1 -1
  15. package/dist/esm/dev/{compareOpportunities.js → mode-parity/compareOpportunities.js} +14 -46
  16. package/dist/esm/dev/{comparePositions.js → mode-parity/comparePositions.js} +16 -39
  17. package/dist/esm/dev/mode-parity/compareRules.js +91 -0
  18. package/dist/esm/dev/{fieldDiff.js → mode-parity/fieldDiff.js} +49 -3
  19. package/dist/esm/dev/mode-parity/scriptUtils.js +121 -0
  20. package/dist/esm/dev/withdrawalUtils.js +1 -1
  21. package/dist/esm/model/compare.schema.js +29 -0
  22. package/dist/esm/model/curators.schema.js +2 -1
  23. package/dist/esm/model/index.js +2 -1
  24. package/dist/esm/model/opportunities.schema.js +13 -12
  25. package/dist/esm/model/positions.schema.js +15 -14
  26. package/dist/esm/model/primitives.schema.js +2 -1
  27. package/dist/esm/plugins/adapters/contracts/ERC4626AdapterContract.js +1 -1
  28. package/dist/esm/plugins/apy/ApyPlugin.js +2 -2
  29. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  30. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  31. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  32. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +1 -1
  33. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  34. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  35. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  36. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  37. package/dist/esm/sdk/base/TokensMeta.js +3 -3
  38. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  39. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  40. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  41. package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
  42. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  43. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  44. package/dist/esm/sdk/pools/PoolService.js +1 -1
  45. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  46. package/dist/types/dev/{compareOpportunities.d.ts → mode-parity/compareOpportunities.d.ts} +5 -5
  47. package/dist/types/dev/{comparePositions.d.ts → mode-parity/comparePositions.d.ts} +5 -5
  48. package/dist/types/dev/mode-parity/compareRules.d.ts +33 -0
  49. package/dist/types/dev/{fieldDiff.d.ts → mode-parity/fieldDiff.d.ts} +47 -5
  50. package/dist/types/dev/mode-parity/scriptUtils.d.ts +47 -0
  51. package/dist/types/model/compare.schema.d.ts +47 -0
  52. package/dist/types/model/index.d.ts +2 -1
  53. package/package.json +1 -1
  54. package/dist/cjs/dev/compareOpportunities.js +0 -137
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_sdk_utils_zod = require("../sdk/utils/zod.js");
3
+ const require_model_compare_schema = require("./compare.schema.js");
3
4
  const require_model_primitives_schema = require("./primitives.schema.js");
4
5
  const require_model_filters = require("./filters.js");
5
6
  const require_model_filters_schema = require("./filters.schema.js");
@@ -56,8 +57,8 @@ const pnlBreakdownSchema = zod_v4.z.object({
56
57
  * {@link PositionCollateral}
57
58
  **/
58
59
  const positionCollateralSchema = zod_v4.z.object({
59
- collateral: require_model_primitives_schema.tokenAmountSchema,
60
- quota: require_model_primitives_schema.tokenAmountSchema,
60
+ collateral: require_model_compare_schema.tolerance(require_model_primitives_schema.tokenAmountSchema, "amount"),
61
+ quota: require_model_compare_schema.tolerance(require_model_primitives_schema.tokenAmountSchema, "amount"),
61
62
  withdrawals: zod_v4.z.array(require_model_liquidations_schema.delayedReceivedAssetSchema)
62
63
  });
63
64
  /**
@@ -68,9 +69,9 @@ const poolPositionSchema = zod_v4.z.object({
68
69
  name: zod_v4.z.string(),
69
70
  chainId: require_model_primitives_schema.chainIdSchema,
70
71
  pool: require_sdk_utils_zod.ZodAddress(),
71
- netValue: require_model_primitives_schema.tokenAmountSchema,
72
+ netValue: require_model_compare_schema.tolerance(require_model_primitives_schema.tokenAmountSchema, "amount"),
72
73
  apy: require_model_opportunities_schema.apyBreakdownSchema,
73
- pnl: pnlBreakdownSchema.optional()
74
+ pnl: require_model_compare_schema.offchainOnly(pnlBreakdownSchema).optional()
74
75
  });
75
76
  /**
76
77
  * {@link BorrowRateBreakdown}
@@ -91,16 +92,16 @@ const strategyPositionSchema = zod_v4.z.object({
91
92
  creditManager: require_sdk_utils_zod.ZodAddress(),
92
93
  creditAccount: require_sdk_utils_zod.ZodAddress(),
93
94
  targetCollateral: require_model_primitives_schema.tokenSchema.nullable(),
94
- leverage: require_model_primitives_schema.leverageSchema,
95
- borrowApy: require_model_primitives_schema.bpsSchema,
96
- netApy: require_model_opportunities_schema.apyBreakdownSchema.optional(),
97
- totalDebt: require_model_primitives_schema.tokenAmountSchema,
98
- totalValue: require_model_primitives_schema.tokenAmountSchema,
99
- healthFactor: require_model_primitives_schema.bpsSchema,
100
- borrowRate: borrowRateBreakdownSchema.optional(),
101
- timeToLiquidation: require_sdk_utils_zod.ZodBigInt().nullable().optional(),
102
- liquidationPrice: require_sdk_utils_zod.ZodBigInt().nullable().optional(),
103
- pnl: pnlBreakdownSchema.optional(),
95
+ leverage: require_model_compare_schema.tolerance(require_model_primitives_schema.leverageSchema, "float"),
96
+ borrowApy: require_model_compare_schema.tolerance(require_model_primitives_schema.bpsSchema, "bps"),
97
+ netApy: require_model_compare_schema.offchainOnly(require_model_opportunities_schema.apyBreakdownSchema).optional(),
98
+ totalDebt: require_model_compare_schema.tolerance(require_model_primitives_schema.tokenAmountSchema, "amount"),
99
+ totalValue: require_model_compare_schema.tolerance(require_model_primitives_schema.tokenAmountSchema, "amount"),
100
+ healthFactor: require_model_compare_schema.tolerance(require_model_primitives_schema.bpsSchema, "bps"),
101
+ borrowRate: require_model_compare_schema.onchainOnly(borrowRateBreakdownSchema).optional(),
102
+ timeToLiquidation: require_model_compare_schema.onchainOnly(require_sdk_utils_zod.ZodBigInt().nullable()).optional(),
103
+ liquidationPrice: require_model_compare_schema.onchainOnly(require_sdk_utils_zod.ZodBigInt().nullable()).optional(),
104
+ pnl: require_model_compare_schema.offchainOnly(pnlBreakdownSchema).optional(),
104
105
  collaterals: zod_v4.z.array(positionCollateralSchema)
105
106
  });
106
107
  /**
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_sdk_utils_zod = require("../sdk/utils/zod.js");
3
+ const require_model_compare_schema = require("./compare.schema.js");
3
4
  let zod_v4 = require("zod/v4");
4
5
  //#region src/model/primitives.schema.ts
5
6
  /**
@@ -40,7 +41,7 @@ const leverageSchema = zod_v4.z.number().nonnegative();
40
41
  **/
41
42
  const amountSchema = zod_v4.z.object({
42
43
  value: require_sdk_utils_zod.ZodBigInt(),
43
- valueUsd: zod_v4.z.number().nullable()
44
+ valueUsd: require_model_compare_schema.tolerance(zod_v4.z.number().nullable(), "usd")
44
45
  });
45
46
  /**
46
47
  * {@link Token}
@@ -1,7 +1,8 @@
1
- import { AxiosCache } from "./axios-cache/AxiosCache.js";
2
- import "./axios-cache/index.js";
3
1
  import { BigIntMath } from "../sdk/utils/bigint-math.js";
4
2
  import { calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, roundUpQuota } from "./utils/creditAccount/quota-utils.js";
3
+ import { EXECUTE_BYTES_SELECTOR, collectTraces, findCallTo, findCallWithInput, findExecuteBytes, resolveProtocolCall } from "./utils/trace.js";
4
+ import { AxiosCache } from "./axios-cache/AxiosCache.js";
5
+ import "./axios-cache/index.js";
5
6
  import { ChartsCreditManagerData } from "./charts/credit-manager.js";
6
7
  import { CREDIT_SESSION_ID_BY_STATUS, CREDIT_SESSION_STATUS_BY_ID, CreditSession, CreditSessionFiltered, UserCreditSessionsBuilder } from "./charts/credit-session.js";
7
8
  import { ChartsPoolData, UserPoolData } from "./charts/pool.js";
@@ -91,6 +92,5 @@ import { getCMYouCanEarn } from "./utils/strategies/strategy-info/get-cm-you-can
91
92
  import { getStrategyInfoCore } from "./utils/strategies/strategy-info/get-strategy-info-core.js";
92
93
  import { getStrategyInfo } from "./utils/strategies/strategy-info/get-strategy-info.js";
93
94
  import { getStrategyYouCanEarn } from "./utils/strategies/strategy-info/get-strategy-you-can-earn.js";
94
- import { EXECUTE_BYTES_SELECTOR, collectTraces, findCallTo, findCallWithInput, findExecuteBytes, resolveProtocolCall } from "./utils/trace.js";
95
95
  import "./utils/index.js";
96
96
  export { AssetUtils, AxiosCache, BONUS_APY_FROM_POINTS, BigIntMath, CREDIT_SESSION_ID_BY_STATUS, CREDIT_SESSION_STATUS_BY_ID, ChartsCreditManagerData, ChartsPoolData, CreditSession, CreditSessionFiltered, EMPTY_ADDRESS, EMPTY_ARRAY, EMPTY_OBJECT, EXECUTE_BYTES_SELECTOR, MIN_HF_LIMITED, PriceUtils, RST_ETH_ADDRESS, TokenData, UserCreditSessionsBuilder, UserPoolData, addAmountInTarget, amountAbcComparator, assetComparator, calcDefaultQuota, calcHealthFactor, calcMaxDebtIncrease, calcMaxLendingDebt, calcOverallAPY, calcQuotaBorrowRate, calcQuotaUpdate, calcRecommendedQuota, calcRelativeBaseBorrowRate, calculateBorrowRateFromUtilization, calculateEarnings, calculateEffectiveBorrowRate, calculateLossCoefficient, calculateMaxLeverageFactor, calculateMaxStrategyDebt, calculateSafeBorrowRate, calculateTotalAPY, calculateTotalPoints, checkBoolean, checkDegenNFT, cmAvailabilityCondition, collectTraces, createLegacyStrategyDataSource, findCallTo, findCallWithInput, findExecuteBytes, getAvailableAndDisabledStrategies, getCMAllowedCollaterals, getCMYouCanEarn, getChainPhantomTokens, getCollateralByDebt, getComplexAPYList, getComplexPointsList, getDefaultAsset, getFactorFromLeverage, getLeverageFromFactor, getListWithAmountInTarget, getNativeTokenAddress, getPointsInfo, getPointsRates, getRateWithFee, getRecommendedDebt, getRecommendedLeverageFactor, getReleasedStrategiesList, getReleasedStrategiesListCore, getSafeBaseBorrowRate, getSingleQuotaBorrowRate, getStrategyCreditManagers, getStrategyCreditManagersList, getStrategyCreditManagersListCore, getStrategyInfo, getStrategyInfoCore, getStrategyMaxAPY, getStrategyPoints, getStrategyYouCanEarn, getTimeToLiquidation, getWalletBalancesAllowedOnCM, isActivatedToken, isApyWithPointsException, isCollateralToken, isCreditManagerUsable, isForbiddenToken, isObtainableToken, isStrategyCMDisabled, isStrategyDisabled, isStrategyEligible, isStrategyReleased, isUsableToken, isValidExtraCollateralToken, isZeroBalance, liquidationPrice, maxAPYFormula, maxLeverage, maxLeverageThreshold, resolveProtocolCall, roundUpQuota, sortAssets, sortBalances, sortStrategyCMsByAvailability, tokensAbcComparator, validateBalance, validateBalances, validateCreditManager, validateHF, validateOpenAccount, validateOpenAccountPoolQuotaStatus, validateOpenAccountPoolStatus, validateQuota, validateTokenToObtain, wrapTokenAddress };
@@ -1,5 +1,6 @@
1
1
  import { BigIntMath } from "../../sdk/utils/bigint-math.js";
2
2
  import { calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, roundUpQuota } from "./creditAccount/quota-utils.js";
3
+ import { EXECUTE_BYTES_SELECTOR, collectTraces, findCallTo, findCallWithInput, findExecuteBytes, resolveProtocolCall } from "./trace.js";
3
4
  import { BONUS_APY_FROM_POINTS } from "./apy/bonus-apy-from-points.js";
4
5
  import { calculateBorrowRateFromUtilization } from "./apy/calculate-borrow-rate-from-utilization.js";
5
6
  import { PriceUtils } from "./price-math.js";
@@ -86,6 +87,5 @@ import { getStrategyInfoCore } from "./strategies/strategy-info/get-strategy-inf
86
87
  import { getStrategyInfo } from "./strategies/strategy-info/get-strategy-info.js";
87
88
  import { getStrategyYouCanEarn } from "./strategies/strategy-info/get-strategy-you-can-earn.js";
88
89
  import "./strategies/index.js";
89
- import { EXECUTE_BYTES_SELECTOR, collectTraces, findCallTo, findCallWithInput, findExecuteBytes, resolveProtocolCall } from "./trace.js";
90
90
  import "./validation/index.js";
91
91
  export { AssetUtils, BONUS_APY_FROM_POINTS, BigIntMath, EMPTY_ADDRESS, EMPTY_ARRAY, EMPTY_OBJECT, EXECUTE_BYTES_SELECTOR, MIN_HF_LIMITED, PriceUtils, RST_ETH_ADDRESS, addAmountInTarget, amountAbcComparator, assetComparator, calcDefaultQuota, calcHealthFactor, calcMaxDebtIncrease, calcMaxLendingDebt, calcOverallAPY, calcQuotaBorrowRate, calcQuotaUpdate, calcRecommendedQuota, calcRelativeBaseBorrowRate, calculateBorrowRateFromUtilization, calculateEarnings, calculateEffectiveBorrowRate, calculateLossCoefficient, calculateMaxLeverageFactor, calculateMaxStrategyDebt, calculateSafeBorrowRate, calculateTotalAPY, calculateTotalPoints, checkBoolean, checkDegenNFT, cmAvailabilityCondition, collectTraces, createLegacyStrategyDataSource, findCallTo, findCallWithInput, findExecuteBytes, getAvailableAndDisabledStrategies, getCMAllowedCollaterals, getCMYouCanEarn, getChainPhantomTokens, getCollateralByDebt, getComplexAPYList, getComplexPointsList, getDefaultAsset, getFactorFromLeverage, getLeverageFromFactor, getListWithAmountInTarget, getNativeTokenAddress, getPointsInfo, getPointsRates, getRateWithFee, getRecommendedDebt, getRecommendedLeverageFactor, getReleasedStrategiesList, getReleasedStrategiesListCore, getSafeBaseBorrowRate, getSingleQuotaBorrowRate, getStrategyCreditManagers, getStrategyCreditManagersList, getStrategyCreditManagersListCore, getStrategyInfo, getStrategyInfoCore, getStrategyMaxAPY, getStrategyPoints, getStrategyYouCanEarn, getTimeToLiquidation, getWalletBalancesAllowedOnCM, isActivatedToken, isApyWithPointsException, isCollateralToken, isCreditManagerUsable, isForbiddenToken, isObtainableToken, isStrategyCMDisabled, isStrategyDisabled, isStrategyEligible, isStrategyReleased, isUsableToken, isValidExtraCollateralToken, isZeroBalance, liquidationPrice, maxAPYFormula, maxLeverage, maxLeverageThreshold, resolveProtocolCall, roundUpQuota, sortAssets, sortBalances, sortStrategyCMsByAvailability, tokensAbcComparator, validateBalance, validateBalances, validateCreditManager, validateHF, validateOpenAccount, validateOpenAccountPoolQuotaStatus, validateOpenAccountPoolStatus, validateQuota, validateTokenToObtain, wrapTokenAddress };
@@ -1,9 +1,9 @@
1
+ import { ierc20Abi } from "../abi/iERC20.js";
1
2
  import { iCreditFacadeV310Abi } from "../abi/310/generated.js";
2
3
  import { AddressMap } from "../sdk/utils/AddressMap.js";
3
4
  import { AddressSet } from "../sdk/utils/AddressSet.js";
4
5
  import { AssetsMap } from "../sdk/utils/AssetsMap.js";
5
6
  import { childLogger } from "../sdk/utils/childLogger.js";
6
- import { ierc20Abi } from "../abi/iERC20.js";
7
7
  import "../sdk/constants/addresses.js";
8
8
  import { MAX_UINT256, PERCENTAGE_FACTOR } from "../sdk/constants/math.js";
9
9
  import { SDKConstruct } from "../sdk/base/SDKConstruct.js";
@@ -1,7 +1,13 @@
1
- import { opportunityId } from "../model/opportunities.js";
2
- import "../model/index.js";
3
- import { countPaths, diffObjects, isAmountWithinTolerance, isBpsWithinTolerance, isUsdWithinTolerance, toCompareCounts, union, withExpected } from "./fieldDiff.js";
4
- //#region src/dev/compareOpportunities.ts
1
+ import { opportunityId } from "../../model/opportunities.js";
2
+ import { poolOpportunitySchema, strategyOpportunitySchema } from "../../model/opportunities.schema.js";
3
+ import "../../model/index.js";
4
+ import { countPaths, diffObjects, toCompareCounts, union } from "./fieldDiff.js";
5
+ import { compileCompareRules, makeTagDiff } from "./compareRules.js";
6
+ //#region src/dev/mode-parity/compareOpportunities.ts
7
+ const tagDiff = makeTagDiff({
8
+ pool: compileCompareRules(poolOpportunitySchema),
9
+ strategy: compileCompareRules(strategyOpportunitySchema)
10
+ });
5
11
  /**
6
12
  * Matches two opportunity listings by {@link opportunityId} and reports every
7
13
  * field the two sources disagree on.
@@ -79,47 +85,6 @@ function toRef(row) {
79
85
  function diffOpportunity(onchain, offchain) {
80
86
  return diffObjects(onchain, offchain).map((diff) => tagDiff(diff, onchain.kind));
81
87
  }
82
- /**
83
- * Paths whose values are basis-point rates that routinely differ by ±1 from
84
- * truncation vs rounding, plus pool `utilization` for the same reason.
85
- **/
86
- const BPS_RATE_PATHS = /* @__PURE__ */ new Set([
87
- "borrowApy",
88
- "supplyApy.organicApy",
89
- "additionalBorrowApy",
90
- "utilization"
91
- ]);
92
- /**
93
- * Amount fields whose bigint `value` moves with expected-liquidity accrual
94
- * between the backend's last sync and the current block. Strategy
95
- * `totalBorrow.value` and `maxBorrowAmount.value` are not in this set: those
96
- * disagreements are formula bugs, not lag.
97
- **/
98
- const LAG_AMOUNT_PATHS = /* @__PURE__ */ new Set(["totalSupply.value", "availableLiquidity.value"]);
99
- /**
100
- * Fields documented `@mode offchain` in the model: the chain has nothing to
101
- * put there, so a presence (or nested) mismatch is expected. Strategy
102
- * `utilization` is in this set; pool `utilization` is not.
103
- **/
104
- function isModeScoped(path, kind) {
105
- if (path === "curator.url") return true;
106
- if (path === "totalApy" || path.endsWith(".totalApy")) return true;
107
- if (path === "rewards" || path.startsWith("rewards[") || path.includes(".rewards[") || path.endsWith(".rewards")) return true;
108
- if (kind !== "strategy") return false;
109
- return path === "utilization" || path === "collateralApy" || path.startsWith("collateralApy.") || path === "maxLeverageApy" || path.startsWith("maxLeverageApy.") || path === "totalValue" || path.startsWith("totalValue.");
110
- }
111
- function tagDiff(diff, kind) {
112
- if (isModeScoped(diff.path, kind)) return withExpected(diff, "mode-scoped");
113
- if (withinTolerance(diff)) return withExpected(diff, "tolerance");
114
- return diff;
115
- }
116
- function withinTolerance(diff) {
117
- if (diff.kind === "usd") return isUsdWithinTolerance(diff.onchain, diff.offchain);
118
- if (diff.kind !== "numeric") return false;
119
- if (BPS_RATE_PATHS.has(diff.path)) return isBpsWithinTolerance(diff.onchain, diff.offchain);
120
- if (LAG_AMOUNT_PATHS.has(diff.path)) return isAmountWithinTolerance(diff.onchain, diff.offchain);
121
- return false;
122
- }
123
88
  function summarize(onchain, offchain, onlyOnchain, onlyOffchain, matched) {
124
89
  const byChain = union(onchain.map((row) => String(row.chainId)), offchain.map((row) => String(row.chainId))).map((chainId) => ({
125
90
  chainId: Number(chainId),
@@ -128,7 +93,10 @@ function summarize(onchain, offchain, onlyOnchain, onlyOffchain, matched) {
128
93
  return {
129
94
  ...toCompareCounts(onchain.length, offchain.length, onlyOnchain.length, onlyOffchain.length, matched),
130
95
  byChain,
131
- diffsByPath: countPaths(matched.flatMap((match) => match.diffs))
96
+ diffsByPath: countPaths(matched.flatMap((match) => match.diffs.map((diff) => ({
97
+ id: match.id,
98
+ diff
99
+ }))))
132
100
  };
133
101
  }
134
102
  //#endregion
@@ -1,7 +1,15 @@
1
- import { positionId } from "../model/positions.js";
2
- import "../model/index.js";
3
- import { USD_RELATIVE_EPSILON, asFiniteNumber, countPaths, diffObjects, isAmountWithinTolerance, isBpsWithinTolerance, isRecord, isUsdWithinTolerance, toCompareCounts, union, withExpected, withinRelative } from "./fieldDiff.js";
4
- //#region src/dev/comparePositions.ts
1
+ import { liquidationPositionSchema } from "../../model/liquidations.schema.js";
2
+ import { positionId } from "../../model/positions.js";
3
+ import { poolPositionSchema, strategyPositionSchema } from "../../model/positions.schema.js";
4
+ import "../../model/index.js";
5
+ import { countPaths, diffObjects, isRecord, toCompareCounts, union } from "./fieldDiff.js";
6
+ import { compileCompareRules, makeTagDiff } from "./compareRules.js";
7
+ //#region src/dev/mode-parity/comparePositions.ts
8
+ const tagDiff = makeTagDiff({
9
+ pool: compileCompareRules(poolPositionSchema),
10
+ strategy: compileCompareRules(strategyPositionSchema),
11
+ liquidation: compileCompareRules(liquidationPositionSchema)
12
+ });
5
13
  /**
6
14
  * Matches two position listings per wallet by {@link positionId} and reports
7
15
  * every field the two sources disagree on.
@@ -104,40 +112,6 @@ function keyOfPositionArray(path, value) {
104
112
  const token = value.collateral.token;
105
113
  return isRecord(token) && typeof token.address === "string" ? token.address : void 0;
106
114
  }
107
- const BPS_RATE_PATHS = /* @__PURE__ */ new Set([
108
- "borrowApy",
109
- "apy.organicApy",
110
- "healthFactor"
111
- ]);
112
- /**
113
- * Amount fields whose bigint `value` moves with interest accrual between the
114
- * backend's last sync and the current block.
115
- **/
116
- function isLagAmountPath(path) {
117
- return path === "totalDebt.value" || path === "totalValue.value" || path === "netValue.value" || path.endsWith(".collateral.value") || path.endsWith(".quota.value");
118
- }
119
- /**
120
- * Fields documented `@mode offchain` or `@mode onchain` in the model.
121
- **/
122
- function isModeScoped(path, kind) {
123
- if (path === "pnl" || path.startsWith("pnl.")) return true;
124
- if (kind === "pool") return path === "apy.totalApy" || path.startsWith("apy.rewards");
125
- if (kind === "strategy") return path === "netApy" || path.startsWith("netApy.") || path === "borrowRate" || path.startsWith("borrowRate.") || path === "timeToLiquidation" || path === "liquidationPrice";
126
- return false;
127
- }
128
- function tagDiff(diff, kind) {
129
- if (isModeScoped(diff.path, kind)) return withExpected(diff, "mode-scoped");
130
- if (withinTolerance(diff)) return withExpected(diff, "tolerance");
131
- return diff;
132
- }
133
- function withinTolerance(diff) {
134
- if (diff.kind === "usd") return isUsdWithinTolerance(diff.onchain, diff.offchain);
135
- if (diff.kind !== "numeric") return false;
136
- if (diff.path === "leverage") return withinRelative(asFiniteNumber(diff.onchain), asFiniteNumber(diff.offchain), USD_RELATIVE_EPSILON);
137
- if (BPS_RATE_PATHS.has(diff.path)) return isBpsWithinTolerance(diff.onchain, diff.offchain);
138
- if (isLagAmountPath(diff.path)) return isAmountWithinTolerance(diff.onchain, diff.offchain);
139
- return false;
140
- }
141
115
  function summarize(inputs, wallets, failed) {
142
116
  const compared = wallets.filter((wallet) => !wallet.error);
143
117
  const allOnchain = inputs.flatMap((input) => input.onchain.data);
@@ -162,7 +136,10 @@ function summarize(inputs, wallets, failed) {
162
136
  walletsFailed: failed,
163
137
  byChain,
164
138
  byWallet,
165
- diffsByPath: countPaths(matched.flatMap((match) => match.diffs))
139
+ diffsByPath: countPaths(matched.flatMap((match) => match.diffs.map((diff) => ({
140
+ id: match.id,
141
+ diff
142
+ }))))
166
143
  };
167
144
  }
168
145
  /**
@@ -0,0 +1,91 @@
1
+ import { compareTagOf } from "../../model/compare.schema.js";
2
+ import { USD_RELATIVE_EPSILON, asFiniteNumber, collapseArrayKeys, isAmountWithinTolerance, isBpsWithinTolerance, isUsdWithinTolerance, withExpected, withinRelative } from "./fieldDiff.js";
3
+ //#region src/dev/mode-parity/compareRules.ts
4
+ /**
5
+ * Walks a schema and records every field that carries compare metadata.
6
+ *
7
+ * `"amount"` on an object (an Amount / TokenAmount) is stored
8
+ * at `<path>.value`; every other tag is stored at the field's own path.
9
+ **/
10
+ function compileCompareRules(schema) {
11
+ const rules = /* @__PURE__ */ new Map();
12
+ walk(schema, "", /* @__PURE__ */ new Set(), rules);
13
+ return rules;
14
+ }
15
+ /**
16
+ * Tags diffs using the rules compiled for each row kind.
17
+ *
18
+ * Mode tags match the path or anything nested under it. Tolerance tags match
19
+ * the path exactly and dispatch on {@link CompareTolerance}.
20
+ **/
21
+ function makeTagDiff(rulesByKind) {
22
+ return (diff, kind) => {
23
+ const rules = rulesByKind[kind];
24
+ if (!rules) return diff;
25
+ const path = collapseArrayKeys(diff.path);
26
+ if (isModeScoped(path, rules)) return withExpected(diff, "mode-scoped");
27
+ const tag = rules.get(path);
28
+ if (tag && typeof tag === "object" && withinTolerance(tag.tolerance, diff)) return withExpected(diff, "tolerance");
29
+ return diff;
30
+ };
31
+ }
32
+ function isModeScoped(path, rules) {
33
+ for (const [rulePath, tag] of rules) {
34
+ if (tag !== "offchainOnly" && tag !== "onchainOnly") continue;
35
+ if (path === rulePath || path.startsWith(`${rulePath}.`) || path.startsWith(`${rulePath}[`)) return true;
36
+ }
37
+ return false;
38
+ }
39
+ function withinTolerance(kind, diff) {
40
+ switch (kind) {
41
+ case "usd": return isUsdWithinTolerance(diff.onchain, diff.offchain);
42
+ case "bps": return isBpsWithinTolerance(diff.onchain, diff.offchain);
43
+ case "amount": return isAmountWithinTolerance(diff.onchain, diff.offchain);
44
+ case "float": return withinRelative(asFiniteNumber(diff.onchain), asFiniteNumber(diff.offchain), USD_RELATIVE_EPSILON);
45
+ }
46
+ }
47
+ function walk(schema, path, seen, rules) {
48
+ if (seen.has(schema)) return;
49
+ const nextSeen = new Set(seen);
50
+ nextSeen.add(schema);
51
+ const tag = compareTagOf(schema);
52
+ if (tag) record(path, tag, schema, rules);
53
+ const def = schema.def;
54
+ switch (def.type) {
55
+ case "optional":
56
+ case "nullable":
57
+ case "default":
58
+ case "prefault":
59
+ case "readonly":
60
+ if (def.innerType) walk(def.innerType, path, nextSeen, rules);
61
+ return;
62
+ case "array":
63
+ if (def.element) walk(def.element, `${path}[]`, nextSeen, rules);
64
+ return;
65
+ case "object":
66
+ if (def.shape) for (const [key, field] of Object.entries(def.shape)) walk(field, join(path, key), nextSeen, rules);
67
+ return;
68
+ case "union":
69
+ for (const option of def.options ?? []) walk(option, path, nextSeen, rules);
70
+ return;
71
+ case "pipe":
72
+ if (def.out) walk(def.out, path, nextSeen, rules);
73
+ return;
74
+ case "lazy":
75
+ if (def.getter) walk(def.getter(), path, nextSeen, rules);
76
+ return;
77
+ default: return;
78
+ }
79
+ }
80
+ function record(path, tag, schema, rules) {
81
+ if (typeof tag === "object" && tag.tolerance === "amount" && schema.def.type === "object") {
82
+ rules.set(join(path, "value"), tag);
83
+ return;
84
+ }
85
+ rules.set(path, tag);
86
+ }
87
+ function join(path, key) {
88
+ return path ? `${path}.${key}` : key;
89
+ }
90
+ //#endregion
91
+ export { compileCompareRules, makeTagDiff };
@@ -1,4 +1,4 @@
1
- //#region src/dev/fieldDiff.ts
1
+ //#region src/dev/mode-parity/fieldDiff.ts
2
2
  /**
3
3
  * Relative drift allowed on {@link Amount.valueUsd} before a USD float is a
4
4
  * real disagreement: 0.1%.
@@ -69,7 +69,7 @@ function withExpected(diff, reason) {
69
69
  **/
70
70
  function countPaths(diffs) {
71
71
  const counts = /* @__PURE__ */ new Map();
72
- for (const diff of diffs) {
72
+ for (const { id, diff } of diffs) {
73
73
  const path = collapseArrayKeys(diff.path);
74
74
  const entry = counts.get(path) ?? {
75
75
  path,
@@ -82,10 +82,31 @@ function countPaths(diffs) {
82
82
  if (diff.expected) entry.expected += 1;
83
83
  else entry.unexpected += 1;
84
84
  if (!entry.kinds.includes(diff.kind)) entry.kinds.push(diff.kind);
85
+ recordWorst(entry, id, diff);
85
86
  counts.set(path, entry);
86
87
  }
87
88
  return [...counts.values()].sort((a, b) => b.unexpected - a.unexpected || b.count - a.count || a.path.localeCompare(b.path));
88
89
  }
90
+ function recordWorst(entry, id, diff) {
91
+ const bps = relativeDiffBps(diff.onchain, diff.offchain);
92
+ if (bps === void 0) return;
93
+ const worst = {
94
+ id,
95
+ path: diff.path,
96
+ bps,
97
+ onchain: diff.onchain,
98
+ offchain: diff.offchain
99
+ };
100
+ if (diff.expected) {
101
+ if (isWorse(worst, entry.worstExpected)) entry.worstExpected = worst;
102
+ return;
103
+ }
104
+ if (isWorse(worst, entry.worstUnexpected)) entry.worstUnexpected = worst;
105
+ }
106
+ function isWorse(candidate, current) {
107
+ if (!current) return true;
108
+ return candidate.bps > current.bps || candidate.bps === current.bps && candidate.id.localeCompare(current.id) < 0;
109
+ }
89
110
  /**
90
111
  * Collapse `collateralTokens[0xa0b8...].symbol` to `collateralTokens[].symbol`.
91
112
  **/
@@ -151,6 +172,31 @@ function withinRelativeBigint(onchain, offchain, epsilon) {
151
172
  function asFiniteNumber(value) {
152
173
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
153
174
  }
175
+ /**
176
+ * Relative difference of two numbers or bigints, in bps:
177
+ * `|a − b| / max(|a|, |b|) * 10_000`. `undefined` when the values are not
178
+ * a comparable pair of finite numbers or of bigints.
179
+ **/
180
+ function relativeDiffBps(onchain, offchain) {
181
+ if (typeof onchain === "bigint" && typeof offchain === "bigint") return relativeDiffBpsBigint(onchain, offchain);
182
+ const left = asFiniteNumber(onchain);
183
+ const right = asFiniteNumber(offchain);
184
+ if (left === void 0 || right === void 0) return;
185
+ const scale = Math.max(Math.abs(left), Math.abs(right));
186
+ return scale === 0 ? 0 : Math.abs(left - right) / scale * 1e4;
187
+ }
188
+ /**
189
+ * Same formula as {@link relativeDiffBps} for bigints, computed in integer
190
+ * arithmetic to milli-bps so a 1e18-scale amount does not round through
191
+ * `Number`.
192
+ **/
193
+ function relativeDiffBpsBigint(onchain, offchain) {
194
+ if (onchain === offchain) return 0;
195
+ const diff = onchain > offchain ? onchain - offchain : offchain - onchain;
196
+ const scale = abs(onchain) > abs(offchain) ? abs(onchain) : abs(offchain);
197
+ if (scale === 0n) return 0;
198
+ return Number(diff * 10000n * 1000n / scale) / 1e3;
199
+ }
154
200
  function union(left, right) {
155
201
  return [.../* @__PURE__ */ new Set([...left, ...right])];
156
202
  }
@@ -221,4 +267,4 @@ function abs(value) {
221
267
  return value < 0n ? -value : value;
222
268
  }
223
269
  //#endregion
224
- export { AMOUNT_RELATIVE_EPSILON, BPS_ABSOLUTE_EPSILON, USD_RELATIVE_EPSILON, asFiniteNumber, collapseArrayKeys, countPaths, diffObjects, diffValue, isAmountWithinTolerance, isBpsWithinTolerance, isRecord, isUsdWithinTolerance, toCompareCounts, union, withExpected, withinRelative, withinRelativeBigint };
270
+ export { AMOUNT_RELATIVE_EPSILON, BPS_ABSOLUTE_EPSILON, USD_RELATIVE_EPSILON, asFiniteNumber, collapseArrayKeys, countPaths, diffObjects, diffValue, isAmountWithinTolerance, isBpsWithinTolerance, isRecord, isUsdWithinTolerance, relativeDiffBps, toCompareCounts, union, withExpected, withinRelative, withinRelativeBigint };
@@ -0,0 +1,121 @@
1
+ import { getAlchemyUrl } from "../providers.js";
2
+ import { pino } from "pino";
3
+ //#region src/dev/mode-parity/scriptUtils.ts
4
+ const NETWORKS = [
5
+ "Mainnet",
6
+ "Monad",
7
+ "Plasma",
8
+ "Somnia",
9
+ "Etherlink"
10
+ ];
11
+ const BACKEND_URL = process.env.BACKEND_URL ?? "https://api.gear-dev.dev";
12
+ const TIMEOUT = 48e4;
13
+ function requireEnv(name) {
14
+ const value = process.env[name];
15
+ if (!value) throw new Error(`${name} is required to reach the chains this script reads`);
16
+ return value;
17
+ }
18
+ function rpcUrls() {
19
+ const alchemyKey = requireEnv("ALCHEMY_KEY");
20
+ const alchemy = (network) => {
21
+ const url = getAlchemyUrl(network, alchemyKey);
22
+ if (!url) throw new Error(`Alchemy serves no URL for ${network}`);
23
+ return url;
24
+ };
25
+ return {
26
+ Mainnet: alchemy("Mainnet"),
27
+ Monad: alchemy("Monad"),
28
+ Plasma: alchemy("Plasma"),
29
+ Somnia: requireEnv("SOMNIA_PROVIDER"),
30
+ Etherlink: requireEnv("ETHERLINK_PROVIDER")
31
+ };
32
+ }
33
+ function createLogger() {
34
+ return pino({
35
+ level: process.env.LOG_LEVEL ?? "info",
36
+ formatters: {
37
+ bindings: () => ({}),
38
+ level: (label) => ({ level: label })
39
+ }
40
+ });
41
+ }
42
+ function errorMessage(error) {
43
+ return error instanceof Error ? error.message : String(error);
44
+ }
45
+ /**
46
+ * Runs `fn` over `items` with at most `concurrency` in flight.
47
+ **/
48
+ async function mapPool(items, concurrency, fn) {
49
+ let next = 0;
50
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
51
+ while (true) {
52
+ const index = next;
53
+ next += 1;
54
+ if (index >= items.length) return;
55
+ await fn(items[index]);
56
+ }
57
+ });
58
+ await Promise.all(workers);
59
+ }
60
+ /**
61
+ * Formats a relative difference in bps as a percent, e.g. 12.5 → `"0.125%"`.
62
+ **/
63
+ function formatBpsAsPercent(bps) {
64
+ if (!Number.isFinite(bps)) return "";
65
+ const percent = bps / 100;
66
+ if (percent === 0) return "0%";
67
+ return `${Math.abs(percent) >= 1 ? trimTrailingZeros(percent.toFixed(3)) : trimTrailingZeros(percent.toPrecision(4))}%`;
68
+ }
69
+ function trimTrailingZeros(value) {
70
+ return value.includes(".") ? value.replace(/\.?0+$/, "") : value;
71
+ }
72
+ function worstColumns(worst) {
73
+ return {
74
+ "max diff": worst ? formatBpsAsPercent(worst.bps) : "",
75
+ "worst entity": worst?.id ?? ""
76
+ };
77
+ }
78
+ /**
79
+ * Prints the shared membership table, the fields that differed most often,
80
+ * and any chain that failed to answer.
81
+ **/
82
+ function printCompareSummary(noun, report, extraLines = []) {
83
+ const { summary } = report;
84
+ console.log(`\n${noun} from ${report.backendUrl} vs the chain`);
85
+ console.table(summary.byChain.map((chain) => ({
86
+ chain: chain.chainId,
87
+ onchain: chain.onchainRows,
88
+ offchain: chain.offchainRows,
89
+ matched: chain.matched,
90
+ identical: chain.identical,
91
+ clean: chain.clean,
92
+ differing: chain.differing,
93
+ "only onchain": chain.onlyOnchain,
94
+ "only offchain": chain.onlyOffchain
95
+ })));
96
+ for (const line of extraLines) console.log(line);
97
+ const unexpected = summary.diffsByPath.filter((entry) => entry.unexpected > 0);
98
+ const expected = summary.diffsByPath.filter((entry) => entry.unexpected === 0 && entry.expected > 0);
99
+ if (unexpected.length) {
100
+ console.log("\nunexpected fields that differed most often:");
101
+ console.table(unexpected.slice(0, 25).map((entry) => ({
102
+ field: entry.path,
103
+ unexpected: entry.unexpected,
104
+ expected: entry.expected,
105
+ kinds: entry.kinds.join(", "),
106
+ ...worstColumns(entry.worstUnexpected)
107
+ })));
108
+ }
109
+ if (expected.length) {
110
+ console.log("\nexpected fields (mode-scoped or within tolerance):");
111
+ console.table(expected.slice(0, 25).map((entry) => ({
112
+ field: entry.path,
113
+ rows: entry.expected,
114
+ kinds: entry.kinds.join(", "),
115
+ ...worstColumns(entry.worstExpected)
116
+ })));
117
+ }
118
+ for (const chain of [...report.onchainChains, ...report.offchainChains]) if (chain.status === "error") console.log(`chain ${chain.chainId} failed on ${chain.source}:`, chain.error);
119
+ }
120
+ //#endregion
121
+ export { BACKEND_URL, NETWORKS, TIMEOUT, createLogger, errorMessage, formatBpsAsPercent, mapPool, printCompareSummary, requireEnv, rpcUrls };
@@ -1,6 +1,6 @@
1
+ import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
1
2
  import { getNetworkType } from "../sdk/chain/chains.js";
2
3
  import { getWithdrawalCompressorAddress } from "../sdk/accounts/withdrawal-compressor/addresses.js";
3
- import { iWithdrawalCompressorV313Abi } from "../abi/IWithdrawalCompressorV313.js";
4
4
  import "../sdk/index.js";
5
5
  import { iMidasDataFeedAbi, iMidasRedemptionVaultAbi, midasGatewayAbi, midasRedeemerAbi, midasRedemptionVaultPhantomTokenAbi, securitizeRedeemerAbi, securitizeRedemptionGatewayAbi, securitizeRedemptionPhantomTokenAbi } from "./withdrawalAbi.js";
6
6
  import { erc20Abi, hexToString, parseAbi, parseEther } from "viem";
@@ -0,0 +1,29 @@
1
+ //#region src/model/compare.schema.ts
2
+ /**
3
+ * Marks a field that only the backend fills.
4
+ **/
5
+ function offchainOnly(schema) {
6
+ return schema.meta({ compare: "offchainOnly" });
7
+ }
8
+ /**
9
+ * Marks a field that only the chain fills.
10
+ **/
11
+ function onchainOnly(schema) {
12
+ return schema.meta({ compare: "onchainOnly" });
13
+ }
14
+ /**
15
+ * Marks a numeric field whose two sources may drift within {@link kind}.
16
+ **/
17
+ function tolerance(schema, kind) {
18
+ return schema.meta({ compare: { tolerance: kind } });
19
+ }
20
+ /**
21
+ * The compare tag registered on a schema, if any.
22
+ **/
23
+ function compareTagOf(schema) {
24
+ const meta = schema.meta();
25
+ if (!meta || !("compare" in meta)) return;
26
+ return meta.compare;
27
+ }
28
+ //#endregion
29
+ export { compareTagOf, offchainOnly, onchainOnly, tolerance };
@@ -1,4 +1,5 @@
1
1
  import { ZodAddress } from "../sdk/utils/zod.js";
2
+ import { offchainOnly } from "./compare.schema.js";
2
3
  import { z } from "zod/v4";
3
4
  //#region src/model/curators.schema.ts
4
5
  /**
@@ -30,7 +31,7 @@ const curatorNameSchema = z.enum([
30
31
  const curatorSchema = z.object({
31
32
  address: ZodAddress(),
32
33
  name: curatorNameSchema.optional(),
33
- url: z.string().nullable()
34
+ url: offchainOnly(z.string().nullable())
34
35
  });
35
36
  //#endregion
36
37
  export { curatorNameSchema, curatorSchema };
@@ -1,4 +1,5 @@
1
1
  import { CHART_METRIC_UNITS, CHART_RANGES, CHART_UNAVAILABLE_CODES, POOL_OPPORTUNITY_CHART_METRICS, POOL_POSITION_CHART_METRICS, STRATEGY_OPPORTUNITY_CHART_METRICS, STRATEGY_POSITION_CHART_METRICS } from "./charts.js";
2
+ import { compareTagOf, offchainOnly, onchainOnly, tolerance } from "./compare.schema.js";
2
3
  import { amountSchema, assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, timestampSchema, tokenAmountSchema, tokenSchema, txCallSchema } from "./primitives.schema.js";
3
4
  import { chartBundleSchemaFor, chartDenominationSchema, chartMetricSchema, chartQueryCodec, chartQueryParamsSchema, chartQuerySchema, chartRangeSchema, chartSeriesSchema, chartValueSchema, chartWindowSchema, poolOpportunityChartMetricSchema, poolPositionChartMetricSchema, strategyOpportunityChartMetricSchema, strategyPositionChartMetricSchema } from "./charts.schema.js";
4
5
  import "./curators.js";
@@ -16,4 +17,4 @@ import { borrowRateBreakdownSchema, pnlBreakdownSchema, pointsProgramPnLSchema,
16
17
  import "./primitives.js";
17
18
  import "./response.js";
18
19
  import { chainFailedSchema, chainMetadataSchema, chainSucceededSchema, dataSourceSchema, responseMetadataSchema, responseSchema } from "./response.schema.js";
19
- export { CHART_METRIC_UNITS, CHART_RANGES, CHART_UNAVAILABLE_CODES, FILTER_ALL, POOL_OPPORTUNITY_CHART_METRICS, POOL_POSITION_CHART_METRICS, STRATEGY_OPPORTUNITY_CHART_METRICS, STRATEGY_POSITION_CHART_METRICS, amountSchema, apyBreakdownSchema, assetTypeSchema, booleanParamSchema, borrowRateBreakdownSchema, bpsSchema, chainFailedSchema, chainIdSchema, chainMetadataSchema, chainSucceededSchema, chartBundleSchemaFor, chartDenominationSchema, chartMetricSchema, chartQueryCodec, chartQueryParamsSchema, chartQuerySchema, chartRangeSchema, chartSeriesSchema, chartValueSchema, chartWindowSchema, curatorNameSchema, curatorSchema, dataSourceSchema, delayedReceivedAssetSchema, encodeFlag, filterAllSchema, filterable, instantReceivedAssetSchema, isFilterSet, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionId, liquidationPositionSchema, matchesLiquidatableAccountFilter, matchesOpportunityFilter, matchesPositionFilter, noticeKindSchema, noticeSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolOpportunityChartMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPositionChartMetricSchema, poolPositionId, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterQueryParamsSchema, positionFilterQuerySchema, positionFilterSchema, positionId, positionKeySchema, positionKindSchema, positionSchema, positionTransactionKindSchema, positionTransactionSchema, positionsTotalsSchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, responseMetadataSchema, responseSchema, rewardsPnLSchema, rewardsSchema, strategyOpportunityChartMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionChartMetricSchema, strategyPositionId, strategyPositionKeySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, txCallSchema };
20
+ export { CHART_METRIC_UNITS, CHART_RANGES, CHART_UNAVAILABLE_CODES, FILTER_ALL, POOL_OPPORTUNITY_CHART_METRICS, POOL_POSITION_CHART_METRICS, STRATEGY_OPPORTUNITY_CHART_METRICS, STRATEGY_POSITION_CHART_METRICS, amountSchema, apyBreakdownSchema, assetTypeSchema, booleanParamSchema, borrowRateBreakdownSchema, bpsSchema, chainFailedSchema, chainIdSchema, chainMetadataSchema, chainSucceededSchema, chartBundleSchemaFor, chartDenominationSchema, chartMetricSchema, chartQueryCodec, chartQueryParamsSchema, chartQuerySchema, chartRangeSchema, chartSeriesSchema, chartValueSchema, chartWindowSchema, compareTagOf, curatorNameSchema, curatorSchema, dataSourceSchema, delayedReceivedAssetSchema, encodeFlag, filterAllSchema, filterable, instantReceivedAssetSchema, isFilterSet, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionId, liquidationPositionSchema, matchesLiquidatableAccountFilter, matchesOpportunityFilter, matchesPositionFilter, noticeKindSchema, noticeSchema, offchainOnly, onchainOnly, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolOpportunityChartMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPositionChartMetricSchema, poolPositionId, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterQueryParamsSchema, positionFilterQuerySchema, positionFilterSchema, positionId, positionKeySchema, positionKindSchema, positionSchema, positionTransactionKindSchema, positionTransactionSchema, positionsTotalsSchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, responseMetadataSchema, responseSchema, rewardsPnLSchema, rewardsSchema, strategyOpportunityChartMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionChartMetricSchema, strategyPositionId, strategyPositionKeySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, tolerance, txCallSchema };