@gearbox-protocol/sdk 15.1.0-next.10 → 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.
- package/dist/cjs/dev/mode-parity/compareOpportunities.js +105 -0
- package/dist/cjs/dev/mode-parity/comparePositions.js +160 -0
- package/dist/cjs/dev/mode-parity/compareRules.js +93 -0
- package/dist/cjs/dev/mode-parity/fieldDiff.js +288 -0
- package/dist/cjs/dev/mode-parity/scriptUtils.js +131 -0
- package/dist/cjs/model/compare.schema.js +33 -0
- package/dist/cjs/model/curators.schema.js +2 -1
- package/dist/cjs/model/index.js +5 -0
- package/dist/cjs/model/opportunities.schema.js +13 -12
- package/dist/cjs/model/positions.schema.js +15 -14
- package/dist/cjs/model/primitives.schema.js +2 -1
- package/dist/cjs/sdk/market/math.js +8 -1
- package/dist/cjs/sdk/pools/PoolService.js +1 -1
- package/dist/cjs/sdk/positions/PositionsService.js +6 -1
- package/dist/esm/common-utils/index.js +3 -3
- package/dist/esm/common-utils/utils/index.js +1 -1
- package/dist/esm/dev/mode-parity/compareOpportunities.js +103 -0
- package/dist/esm/dev/mode-parity/comparePositions.js +158 -0
- package/dist/esm/dev/mode-parity/compareRules.js +91 -0
- package/dist/esm/dev/mode-parity/fieldDiff.js +270 -0
- package/dist/esm/dev/mode-parity/scriptUtils.js +121 -0
- package/dist/esm/model/compare.schema.js +29 -0
- package/dist/esm/model/curators.schema.js +2 -1
- package/dist/esm/model/index.js +2 -1
- package/dist/esm/model/opportunities.schema.js +13 -12
- package/dist/esm/model/positions.schema.js +15 -14
- package/dist/esm/model/primitives.schema.js +2 -1
- package/dist/esm/plugins/apy/ApyPlugin.js +2 -2
- package/dist/esm/sdk/market/math.js +8 -1
- package/dist/esm/sdk/pools/PoolService.js +1 -1
- package/dist/esm/sdk/positions/PositionsService.js +6 -1
- package/dist/types/dev/{compareOpportunities.d.ts → mode-parity/compareOpportunities.d.ts} +18 -66
- package/dist/types/dev/mode-parity/comparePositions.d.ts +149 -0
- package/dist/types/dev/mode-parity/compareRules.d.ts +33 -0
- package/dist/types/dev/mode-parity/fieldDiff.d.ts +209 -0
- package/dist/types/dev/mode-parity/scriptUtils.d.ts +47 -0
- package/dist/types/model/compare.schema.d.ts +47 -0
- package/dist/types/model/index.d.ts +2 -1
- package/dist/types/sdk/market/math.d.ts +2 -0
- package/package.json +1 -1
- package/dist/cjs/dev/compareOpportunities.js +0 -218
- package/dist/esm/dev/compareOpportunities.js +0 -216
package/dist/esm/model/index.js
CHANGED
|
@@ -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 };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ZodAddress } from "../sdk/utils/zod.js";
|
|
2
|
+
import { offchainOnly, tolerance } from "./compare.schema.js";
|
|
2
3
|
import { amountSchema, assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, timestampSchema, tokenSchema } from "./primitives.schema.js";
|
|
3
4
|
import { curatorSchema } from "./curators.schema.js";
|
|
4
5
|
import { isFilterSet } from "./filters.js";
|
|
@@ -45,9 +46,9 @@ const rewardsSchema = z.discriminatedUnion("kind", [tokenRewardsSchema, pointRew
|
|
|
45
46
|
* {@link ApyBreakdown}
|
|
46
47
|
**/
|
|
47
48
|
const apyBreakdownSchema = z.object({
|
|
48
|
-
totalApy: bpsSchema.optional(),
|
|
49
|
-
organicApy: bpsSchema,
|
|
50
|
-
rewards: z.array(rewardsSchema).optional()
|
|
49
|
+
totalApy: offchainOnly(bpsSchema).optional(),
|
|
50
|
+
organicApy: tolerance(bpsSchema, "bps"),
|
|
51
|
+
rewards: offchainOnly(z.array(rewardsSchema)).optional()
|
|
51
52
|
});
|
|
52
53
|
/**
|
|
53
54
|
* {@link OpportunityBase}
|
|
@@ -70,9 +71,9 @@ const poolOpportunitySchema = z.object({
|
|
|
70
71
|
...opportunityBaseSchema.shape,
|
|
71
72
|
kind: z.literal("pool"),
|
|
72
73
|
pool: ZodAddress(),
|
|
73
|
-
totalSupply: amountSchema,
|
|
74
|
-
availableLiquidity: amountSchema,
|
|
75
|
-
utilization: bpsSchema,
|
|
74
|
+
totalSupply: tolerance(amountSchema, "amount"),
|
|
75
|
+
availableLiquidity: tolerance(amountSchema, "amount"),
|
|
76
|
+
utilization: tolerance(bpsSchema, "bps"),
|
|
76
77
|
supplyApy: apyBreakdownSchema
|
|
77
78
|
});
|
|
78
79
|
/**
|
|
@@ -87,12 +88,12 @@ const strategyOpportunitySchema = z.object({
|
|
|
87
88
|
liquidationPremium: bpsSchema,
|
|
88
89
|
liquidationFee: bpsSchema,
|
|
89
90
|
expirationDate: timestampSchema.nullable(),
|
|
90
|
-
collateralApy: apyBreakdownSchema.optional(),
|
|
91
|
-
maxLeverageApy: apyBreakdownSchema.optional(),
|
|
92
|
-
borrowApy: bpsSchema.optional(),
|
|
93
|
-
additionalBorrowApy: bpsSchema.optional(),
|
|
94
|
-
totalValue: amountSchema.optional(),
|
|
95
|
-
utilization: bpsSchema.optional(),
|
|
91
|
+
collateralApy: offchainOnly(apyBreakdownSchema).optional(),
|
|
92
|
+
maxLeverageApy: offchainOnly(apyBreakdownSchema).optional(),
|
|
93
|
+
borrowApy: tolerance(bpsSchema, "bps").optional(),
|
|
94
|
+
additionalBorrowApy: tolerance(bpsSchema, "bps").optional(),
|
|
95
|
+
totalValue: offchainOnly(amountSchema).optional(),
|
|
96
|
+
utilization: offchainOnly(bpsSchema).optional(),
|
|
96
97
|
maxBorrowAmount: amountSchema,
|
|
97
98
|
maxLeverage: leverageSchema
|
|
98
99
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ZodAddress, ZodBigInt, ZodHex } from "../sdk/utils/zod.js";
|
|
2
|
+
import { offchainOnly, onchainOnly, tolerance } from "./compare.schema.js";
|
|
2
3
|
import { assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, timestampSchema, tokenAmountSchema, tokenSchema } from "./primitives.schema.js";
|
|
3
4
|
import { isFilterSet } from "./filters.js";
|
|
4
5
|
import { booleanParamSchema, encodeFlag, filterable } from "./filters.schema.js";
|
|
@@ -55,8 +56,8 @@ const pnlBreakdownSchema = z.object({
|
|
|
55
56
|
* {@link PositionCollateral}
|
|
56
57
|
**/
|
|
57
58
|
const positionCollateralSchema = z.object({
|
|
58
|
-
collateral: tokenAmountSchema,
|
|
59
|
-
quota: tokenAmountSchema,
|
|
59
|
+
collateral: tolerance(tokenAmountSchema, "amount"),
|
|
60
|
+
quota: tolerance(tokenAmountSchema, "amount"),
|
|
60
61
|
withdrawals: z.array(delayedReceivedAssetSchema)
|
|
61
62
|
});
|
|
62
63
|
/**
|
|
@@ -67,9 +68,9 @@ const poolPositionSchema = z.object({
|
|
|
67
68
|
name: z.string(),
|
|
68
69
|
chainId: chainIdSchema,
|
|
69
70
|
pool: ZodAddress(),
|
|
70
|
-
netValue: tokenAmountSchema,
|
|
71
|
+
netValue: tolerance(tokenAmountSchema, "amount"),
|
|
71
72
|
apy: apyBreakdownSchema,
|
|
72
|
-
pnl: pnlBreakdownSchema.optional()
|
|
73
|
+
pnl: offchainOnly(pnlBreakdownSchema).optional()
|
|
73
74
|
});
|
|
74
75
|
/**
|
|
75
76
|
* {@link BorrowRateBreakdown}
|
|
@@ -90,16 +91,16 @@ const strategyPositionSchema = z.object({
|
|
|
90
91
|
creditManager: ZodAddress(),
|
|
91
92
|
creditAccount: ZodAddress(),
|
|
92
93
|
targetCollateral: tokenSchema.nullable(),
|
|
93
|
-
leverage: leverageSchema,
|
|
94
|
-
borrowApy: bpsSchema,
|
|
95
|
-
netApy: apyBreakdownSchema.optional(),
|
|
96
|
-
totalDebt: tokenAmountSchema,
|
|
97
|
-
totalValue: tokenAmountSchema,
|
|
98
|
-
healthFactor: bpsSchema,
|
|
99
|
-
borrowRate: borrowRateBreakdownSchema.optional(),
|
|
100
|
-
timeToLiquidation: ZodBigInt().nullable().optional(),
|
|
101
|
-
liquidationPrice: ZodBigInt().nullable().optional(),
|
|
102
|
-
pnl: pnlBreakdownSchema.optional(),
|
|
94
|
+
leverage: tolerance(leverageSchema, "float"),
|
|
95
|
+
borrowApy: tolerance(bpsSchema, "bps"),
|
|
96
|
+
netApy: offchainOnly(apyBreakdownSchema).optional(),
|
|
97
|
+
totalDebt: tolerance(tokenAmountSchema, "amount"),
|
|
98
|
+
totalValue: tolerance(tokenAmountSchema, "amount"),
|
|
99
|
+
healthFactor: tolerance(bpsSchema, "bps"),
|
|
100
|
+
borrowRate: onchainOnly(borrowRateBreakdownSchema).optional(),
|
|
101
|
+
timeToLiquidation: onchainOnly(ZodBigInt().nullable()).optional(),
|
|
102
|
+
liquidationPrice: onchainOnly(ZodBigInt().nullable()).optional(),
|
|
103
|
+
pnl: offchainOnly(pnlBreakdownSchema).optional(),
|
|
103
104
|
collaterals: z.array(positionCollateralSchema)
|
|
104
105
|
});
|
|
105
106
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ZodAddress, ZodBigInt, ZodHex } from "../sdk/utils/zod.js";
|
|
2
|
+
import { tolerance } from "./compare.schema.js";
|
|
2
3
|
import { z } from "zod/v4";
|
|
3
4
|
//#region src/model/primitives.schema.ts
|
|
4
5
|
/**
|
|
@@ -39,7 +40,7 @@ const leverageSchema = z.number().nonnegative();
|
|
|
39
40
|
**/
|
|
40
41
|
const amountSchema = z.object({
|
|
41
42
|
value: ZodBigInt(),
|
|
42
|
-
valueUsd: z.number().nullable()
|
|
43
|
+
valueUsd: tolerance(z.number().nullable(), "usd")
|
|
43
44
|
});
|
|
44
45
|
/**
|
|
45
46
|
* {@link Token}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { AxiosCache } from "../../common-utils/axios-cache/AxiosCache.js";
|
|
2
|
-
import "../../common-utils/axios-cache/index.js";
|
|
3
1
|
import { AddressMap } from "../../sdk/utils/AddressMap.js";
|
|
4
2
|
import { AP_MARKET_COMPRESSOR } from "../../sdk/constants/address-provider.js";
|
|
5
3
|
import { PERCENTAGE_DECIMALS } from "../../sdk/constants/math.js";
|
|
@@ -10,6 +8,8 @@ import { hexEq } from "../../sdk/utils/hex.js";
|
|
|
10
8
|
import { marketCompressorAbi } from "../../abi/compressors/marketCompressor.js";
|
|
11
9
|
import { BasePlugin } from "../../sdk/plugins/BasePlugin.js";
|
|
12
10
|
import "../../sdk/index.js";
|
|
11
|
+
import { AxiosCache } from "../../common-utils/axios-cache/AxiosCache.js";
|
|
12
|
+
import "../../common-utils/axios-cache/index.js";
|
|
13
13
|
import { getStrategyCreditManagersListCore } from "../../common-utils/utils/strategies/credit-managers/get-strategy-credit-managers-list-core.js";
|
|
14
14
|
import { getAvailableAndDisabledStrategies } from "../../common-utils/utils/strategies/lists/get-available-and-disabled-strategies.js";
|
|
15
15
|
import { getReleasedStrategiesListCore } from "../../common-utils/utils/strategies/lists/get-released-strategies-list-core.js";
|
|
@@ -23,8 +23,15 @@ function rayToBps(ray) {
|
|
|
23
23
|
return Number(ray * PERCENTAGE_FACTOR / RAY);
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
+
* Raw 8-decimal USD values below this are compressor leftover dust (typically
|
|
27
|
+
* 1-wei balances on empty accounts) and report as `0`.
|
|
28
|
+
**/
|
|
29
|
+
const USD_DUST_THRESHOLD = 1000n;
|
|
30
|
+
/**
|
|
26
31
|
* Converts a USD value in the oracle's 8-decimal fixed point to a float.
|
|
27
32
|
*
|
|
33
|
+
* Values below {@link USD_DUST_THRESHOLD} report as `0`.
|
|
34
|
+
*
|
|
28
35
|
* @example
|
|
29
36
|
* ```ts
|
|
30
37
|
* // usd: $1500.50 in 8-decimal fixed point
|
|
@@ -32,7 +39,7 @@ function rayToBps(ray) {
|
|
|
32
39
|
* ```
|
|
33
40
|
**/
|
|
34
41
|
function usdToNumber(usd) {
|
|
35
|
-
return Number(usd) / Number(PRICE_DECIMALS);
|
|
42
|
+
return usd < USD_DUST_THRESHOLD ? 0 : Number(usd) / Number(PRICE_DECIMALS);
|
|
36
43
|
}
|
|
37
44
|
/**
|
|
38
45
|
* Share of capital currently borrowed, in basis points. Returns `0` when there
|
|
@@ -414,7 +414,7 @@ var PoolService = class extends SDKConstruct {
|
|
|
414
414
|
const { pool } = market.pool;
|
|
415
415
|
return {
|
|
416
416
|
kind: "pool",
|
|
417
|
-
name:
|
|
417
|
+
name: this.sdk.tokensMeta.mustGetToken(pool.address).name,
|
|
418
418
|
chainId: this.chainId,
|
|
419
419
|
pool: pool.address,
|
|
420
420
|
netValue: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AddressMap } from "../utils/AddressMap.js";
|
|
2
2
|
import "../constants/math.js";
|
|
3
3
|
import "../constants/index.js";
|
|
4
|
+
import { hexEq } from "../utils/hex.js";
|
|
4
5
|
import "../utils/index.js";
|
|
5
6
|
import { SDKConstruct } from "../base/SDKConstruct.js";
|
|
6
7
|
import "../base/index.js";
|
|
@@ -146,7 +147,11 @@ var PositionsService = class extends SDKConstruct {
|
|
|
146
147
|
const { pool } = market.pool;
|
|
147
148
|
const token = this.sdk.tokensMeta.mustGetToken(market.unwrappedUnderlying);
|
|
148
149
|
const totalDebtValue = ca.debt + ca.accruedInterest + ca.accruedFees;
|
|
149
|
-
|
|
150
|
+
let collateral = dominantCollateral(ca, market);
|
|
151
|
+
if (collateral) {
|
|
152
|
+
const source = this.sdk.withdrawalCompressor?.getWithdrawalSourceToken(collateral);
|
|
153
|
+
if (source) collateral = hexEq(source, market.underlying) ? void 0 : source;
|
|
154
|
+
}
|
|
150
155
|
const snapshot = accountSnapshotFromCreditAccountData(ca);
|
|
151
156
|
const borrowRate = this.borrowRate(snapshot);
|
|
152
157
|
const timeToLiquidation = this.timeToLiquidation(snapshot);
|
|
@@ -1,38 +1,10 @@
|
|
|
1
|
-
import { ChainId } from "
|
|
2
|
-
import { Opportunity, OpportunityId, OpportunityKind } from "
|
|
3
|
-
import { ChainMetadata, DataResponse } from "
|
|
4
|
-
import "
|
|
1
|
+
import { ChainId } from "../../model/primitives.js";
|
|
2
|
+
import { Opportunity, OpportunityId, OpportunityKind } from "../../model/opportunities.js";
|
|
3
|
+
import { ChainMetadata, DataResponse } from "../../model/response.js";
|
|
4
|
+
import "../../model/index.js";
|
|
5
|
+
import { ChainCompareCounts, CompareCounts, DiffKind, DiffPathCount, ExpectedDiffReason, FieldDiff } from "./fieldDiff.js";
|
|
5
6
|
import { Address } from "viem";
|
|
6
|
-
//#region src/dev/compareOpportunities.d.ts
|
|
7
|
-
/**
|
|
8
|
-
* What kind of disagreement a {@link FieldDiff} describes, so that a reader can
|
|
9
|
-
* bucket the report without re-deriving it from the values.
|
|
10
|
-
*
|
|
11
|
-
* - `"presence"` — one side has no value at all (`undefined` or `null`).
|
|
12
|
-
* - `"usd"` — an {@link Amount.valueUsd}, i.e. a price-derived float.
|
|
13
|
-
* - `"numeric"` — any other number or bigint.
|
|
14
|
-
* - `"other"` — everything else: strings, booleans, array shapes.
|
|
15
|
-
**/
|
|
16
|
-
type DiffKind = "presence" | "usd" | "numeric" | "other";
|
|
17
|
-
/**
|
|
18
|
-
* One field of one opportunity where the two sources disagree.
|
|
19
|
-
**/
|
|
20
|
-
interface FieldDiff {
|
|
21
|
-
/**
|
|
22
|
-
* Dotted path into the row, with array elements keyed by their own identity
|
|
23
|
-
* rather than by index, e.g. `collateralTokens[0xa0b8...].symbol`.
|
|
24
|
-
**/
|
|
25
|
-
path: string;
|
|
26
|
-
/**
|
|
27
|
-
* Value the chain reported, `undefined` when it has no such field.
|
|
28
|
-
**/
|
|
29
|
-
onchain: unknown;
|
|
30
|
-
/**
|
|
31
|
-
* Value the backend reported, see {@link onchain}.
|
|
32
|
-
**/
|
|
33
|
-
offchain: unknown;
|
|
34
|
-
kind: DiffKind;
|
|
35
|
-
}
|
|
7
|
+
//#region src/dev/mode-parity/compareOpportunities.d.ts
|
|
36
8
|
/**
|
|
37
9
|
* Enough of an opportunity to identify it in a report without carrying the
|
|
38
10
|
* whole row.
|
|
@@ -64,36 +36,16 @@ interface OpportunityMatch {
|
|
|
64
36
|
**/
|
|
65
37
|
onchainName: string;
|
|
66
38
|
offchainName: string;
|
|
39
|
+
/**
|
|
40
|
+
* No diffs at all, including the documented offchain-only ones.
|
|
41
|
+
**/
|
|
67
42
|
identical: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* No unexpected diffs: every disagreement is mode-scoped or within tolerance.
|
|
45
|
+
**/
|
|
46
|
+
clean: boolean;
|
|
68
47
|
diffs: FieldDiff[];
|
|
69
48
|
}
|
|
70
|
-
/**
|
|
71
|
-
* How often one field disagreed across all matched rows, with array keys
|
|
72
|
-
* collapsed, e.g. `collateralTokens[].symbol`.
|
|
73
|
-
**/
|
|
74
|
-
interface DiffPathCount {
|
|
75
|
-
path: string;
|
|
76
|
-
kinds: DiffKind[];
|
|
77
|
-
count: number;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Counts of one chain, or of the whole report when `chainId` is absent.
|
|
81
|
-
**/
|
|
82
|
-
interface CompareCounts {
|
|
83
|
-
onchainRows: number;
|
|
84
|
-
offchainRows: number;
|
|
85
|
-
matched: number;
|
|
86
|
-
identical: number;
|
|
87
|
-
differing: number;
|
|
88
|
-
onlyOnchain: number;
|
|
89
|
-
onlyOffchain: number;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Counts of one chain.
|
|
93
|
-
**/
|
|
94
|
-
interface ChainCompareCounts extends CompareCounts {
|
|
95
|
-
chainId: ChainId;
|
|
96
|
-
}
|
|
97
49
|
/**
|
|
98
50
|
* Totals of the comparison plus the fields that differed most often.
|
|
99
51
|
**/
|
|
@@ -139,10 +91,10 @@ interface CompareOpportunitiesInput {
|
|
|
139
91
|
* Matches two opportunity listings by {@link opportunityId} and reports every
|
|
140
92
|
* field the two sources disagree on.
|
|
141
93
|
*
|
|
142
|
-
* Nothing is filtered out
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
94
|
+
* Nothing is filtered out. A field only the backend can fill, or a USD value
|
|
95
|
+
* that drifted within snapshot-lag noise, is still reported — tagged
|
|
96
|
+
* {@link FieldDiff.expected} so that {@link CompareCounts.clean} can ignore it
|
|
97
|
+
* while {@link CompareCounts.identical} stays strict.
|
|
146
98
|
**/
|
|
147
99
|
declare function compareOpportunities(input: CompareOpportunitiesInput): OpportunityCompareReport;
|
|
148
100
|
/**
|
|
@@ -150,4 +102,4 @@ declare function compareOpportunities(input: CompareOpportunitiesInput): Opportu
|
|
|
150
102
|
**/
|
|
151
103
|
declare function diffOpportunity(onchain: Opportunity, offchain: Opportunity): FieldDiff[];
|
|
152
104
|
//#endregion
|
|
153
|
-
export { ChainCompareCounts, CompareCounts, CompareOpportunitiesInput, CompareSummary, DiffKind, DiffPathCount, FieldDiff, OpportunityCompareReport, OpportunityMatch, OpportunityRef, compareOpportunities, diffOpportunity };
|
|
105
|
+
export { type ChainCompareCounts, type CompareCounts, CompareOpportunitiesInput, CompareSummary, type DiffKind, type DiffPathCount, type ExpectedDiffReason, type FieldDiff, OpportunityCompareReport, OpportunityMatch, OpportunityRef, compareOpportunities, diffOpportunity };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { ChainId } from "../../model/primitives.js";
|
|
2
|
+
import { Position, PositionId, PositionKind } from "../../model/positions.js";
|
|
3
|
+
import { ChainMetadata, DataResponse } from "../../model/response.js";
|
|
4
|
+
import "../../model/index.js";
|
|
5
|
+
import { ChainCompareCounts, CompareCounts, DiffPathCount, FieldDiff } from "./fieldDiff.js";
|
|
6
|
+
import { Address } from "viem";
|
|
7
|
+
//#region src/dev/mode-parity/comparePositions.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Enough of a position to identify it in a report without carrying the whole
|
|
10
|
+
* row.
|
|
11
|
+
**/
|
|
12
|
+
interface PositionRef {
|
|
13
|
+
id: PositionId;
|
|
14
|
+
kind: PositionKind;
|
|
15
|
+
chainId: ChainId;
|
|
16
|
+
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* Set on a pool position.
|
|
19
|
+
**/
|
|
20
|
+
pool?: Address;
|
|
21
|
+
/**
|
|
22
|
+
* Set on a strategy position.
|
|
23
|
+
**/
|
|
24
|
+
creditAccount?: Address;
|
|
25
|
+
creditManager?: Address;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One position both sources listed for a wallet, and everything they disagree
|
|
29
|
+
* on.
|
|
30
|
+
**/
|
|
31
|
+
interface PositionMatch {
|
|
32
|
+
id: PositionId;
|
|
33
|
+
kind: PositionKind;
|
|
34
|
+
chainId: ChainId;
|
|
35
|
+
onchainName: string;
|
|
36
|
+
offchainName: string;
|
|
37
|
+
/**
|
|
38
|
+
* No diffs at all, including the documented mode-scoped ones.
|
|
39
|
+
**/
|
|
40
|
+
identical: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* No unexpected diffs: every disagreement is mode-scoped or within tolerance.
|
|
43
|
+
**/
|
|
44
|
+
clean: boolean;
|
|
45
|
+
diffs: FieldDiff[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* One wallet's comparison, or the error that stopped it.
|
|
49
|
+
**/
|
|
50
|
+
interface WalletComparison {
|
|
51
|
+
wallet: Address;
|
|
52
|
+
/**
|
|
53
|
+
* Why both listings of this wallet could not be read. When set, the rest of
|
|
54
|
+
* the fields are empty.
|
|
55
|
+
**/
|
|
56
|
+
error?: string;
|
|
57
|
+
onlyOnchain: PositionRef[];
|
|
58
|
+
onlyOffchain: PositionRef[];
|
|
59
|
+
matched: PositionMatch[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Counts of one wallet.
|
|
63
|
+
**/
|
|
64
|
+
interface WalletCompareCounts extends CompareCounts {
|
|
65
|
+
wallet: Address;
|
|
66
|
+
/**
|
|
67
|
+
* Present when the wallet's listings could not be read.
|
|
68
|
+
**/
|
|
69
|
+
error?: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Totals of the comparison plus the fields that differed most often.
|
|
73
|
+
**/
|
|
74
|
+
interface PositionsCompareSummary extends CompareCounts {
|
|
75
|
+
wallets: number;
|
|
76
|
+
/**
|
|
77
|
+
* Wallets whose listings were read and that have no membership gaps and no
|
|
78
|
+
* unexpected field diffs.
|
|
79
|
+
**/
|
|
80
|
+
walletsClean: number;
|
|
81
|
+
walletsFailed: number;
|
|
82
|
+
byChain: ChainCompareCounts[];
|
|
83
|
+
byWallet: WalletCompareCounts[];
|
|
84
|
+
diffsByPath: DiffPathCount[];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Everything one comparison run produced, ready to be written out as JSON.
|
|
88
|
+
**/
|
|
89
|
+
interface PositionsCompareReport {
|
|
90
|
+
generatedAt: string;
|
|
91
|
+
backendUrl: string;
|
|
92
|
+
networks: string[];
|
|
93
|
+
/**
|
|
94
|
+
* Per-chain metadata collected from the on-chain reads, which says which
|
|
95
|
+
* block each chain answered from. Taken from the first successful wallet
|
|
96
|
+
* listing of each chain.
|
|
97
|
+
**/
|
|
98
|
+
onchainChains: ChainMetadata[];
|
|
99
|
+
/**
|
|
100
|
+
* Per-chain metadata of the backend reads, see {@link onchainChains}.
|
|
101
|
+
**/
|
|
102
|
+
offchainChains: ChainMetadata[];
|
|
103
|
+
summary: PositionsCompareSummary;
|
|
104
|
+
wallets: WalletComparison[];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Both listings of one wallet.
|
|
108
|
+
**/
|
|
109
|
+
interface WalletPositions {
|
|
110
|
+
wallet: Address;
|
|
111
|
+
onchain: DataResponse<Position[]>;
|
|
112
|
+
offchain: DataResponse<Position[]>;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* A wallet whose listings could not be read from one or both sources.
|
|
116
|
+
**/
|
|
117
|
+
interface WalletPositionsFailure {
|
|
118
|
+
wallet: Address;
|
|
119
|
+
error: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The per-wallet listings to compare, plus what the run was pointed at.
|
|
123
|
+
**/
|
|
124
|
+
interface ComparePositionsInput {
|
|
125
|
+
wallets: WalletPositions[];
|
|
126
|
+
failures?: WalletPositionsFailure[];
|
|
127
|
+
backendUrl: string;
|
|
128
|
+
networks: string[];
|
|
129
|
+
/**
|
|
130
|
+
* ISO timestamp stamped onto the report, defaulting to now. Pinned by tests.
|
|
131
|
+
**/
|
|
132
|
+
generatedAt?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Matches two position listings per wallet by {@link positionId} and reports
|
|
136
|
+
* every field the two sources disagree on.
|
|
137
|
+
*
|
|
138
|
+
* Nothing is filtered out. A field only one mode can fill, or a USD value that
|
|
139
|
+
* drifted within snapshot-lag noise, is still reported — tagged
|
|
140
|
+
* {@link FieldDiff.expected} so that {@link CompareCounts.clean} can ignore it
|
|
141
|
+
* while {@link CompareCounts.identical} stays strict.
|
|
142
|
+
**/
|
|
143
|
+
declare function comparePositions(input: ComparePositionsInput): PositionsCompareReport;
|
|
144
|
+
/**
|
|
145
|
+
* Every field two versions of one position disagree on.
|
|
146
|
+
**/
|
|
147
|
+
declare function diffPosition(onchain: Position, offchain: Position): FieldDiff[];
|
|
148
|
+
//#endregion
|
|
149
|
+
export { ComparePositionsInput, PositionMatch, PositionRef, PositionsCompareReport, PositionsCompareSummary, WalletCompareCounts, WalletComparison, WalletPositions, WalletPositionsFailure, comparePositions, diffPosition };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CompareTag } from "../../model/compare.schema.js";
|
|
2
|
+
import { FieldDiff } from "./fieldDiff.js";
|
|
3
|
+
import { z } from "zod/v4";
|
|
4
|
+
//#region src/dev/mode-parity/compareRules.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Collapsed-path → tag map compiled from a zod schema, e.g.
|
|
7
|
+
* `apy.totalApy` → `"offchainOnly"`, `totalDebt.value` → `{ tolerance: amount }`.
|
|
8
|
+
**/
|
|
9
|
+
type CompareRuleMap = Map<string, CompareTag>;
|
|
10
|
+
/**
|
|
11
|
+
* Walks a schema and records every field that carries compare metadata.
|
|
12
|
+
*
|
|
13
|
+
* `"amount"` on an object (an Amount / TokenAmount) is stored
|
|
14
|
+
* at `<path>.value`; every other tag is stored at the field's own path.
|
|
15
|
+
**/
|
|
16
|
+
declare function compileCompareRules(schema: z.ZodType): CompareRuleMap;
|
|
17
|
+
/**
|
|
18
|
+
* Rules compiled for each row kind, e.g. `"pool"` vs `"strategy"`.
|
|
19
|
+
**/
|
|
20
|
+
type CompareRulesByKind = Record<string, CompareRuleMap>;
|
|
21
|
+
/**
|
|
22
|
+
* Tags one field diff using the rules compiled for its row kind.
|
|
23
|
+
**/
|
|
24
|
+
type TagDiff = (diff: FieldDiff, kind: string) => FieldDiff;
|
|
25
|
+
/**
|
|
26
|
+
* Tags diffs using the rules compiled for each row kind.
|
|
27
|
+
*
|
|
28
|
+
* Mode tags match the path or anything nested under it. Tolerance tags match
|
|
29
|
+
* the path exactly and dispatch on {@link CompareTolerance}.
|
|
30
|
+
**/
|
|
31
|
+
declare function makeTagDiff(rulesByKind: CompareRulesByKind): TagDiff;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { CompareRuleMap, CompareRulesByKind, TagDiff, compileCompareRules, makeTagDiff };
|