@gearbox-protocol/sdk 15.1.0-next.11 → 15.1.0-next.13
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/{comparePositions.js → mode-parity/comparePositions.js} +23 -46
- package/dist/cjs/dev/mode-parity/compareRules.js +93 -0
- package/dist/cjs/dev/{fieldDiff.js → mode-parity/fieldDiff.js} +49 -2
- 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/new-sdk/index.js +3 -3
- package/dist/cjs/new-sdk/opportunities/OpportunitiesNamespace.js +8 -8
- package/dist/cjs/new-sdk/{simulate/SimulateApi.js → prepare/PrepareApi.js} +21 -49
- package/dist/cjs/new-sdk/prepare/index.js +4 -0
- package/dist/esm/dev/{compareOpportunities.js → mode-parity/compareOpportunities.js} +14 -46
- package/dist/esm/dev/{comparePositions.js → mode-parity/comparePositions.js} +16 -39
- package/dist/esm/dev/mode-parity/compareRules.js +91 -0
- package/dist/esm/dev/{fieldDiff.js → mode-parity/fieldDiff.js} +49 -3
- 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/new-sdk/index.js +3 -3
- package/dist/esm/new-sdk/opportunities/OpportunitiesNamespace.js +8 -8
- package/dist/esm/new-sdk/{simulate/SimulateApi.js → prepare/PrepareApi.js} +21 -49
- package/dist/esm/new-sdk/prepare/index.js +3 -0
- package/dist/types/dev/{compareOpportunities.d.ts → mode-parity/compareOpportunities.d.ts} +5 -5
- package/dist/types/dev/{comparePositions.d.ts → mode-parity/comparePositions.d.ts} +5 -5
- package/dist/types/dev/mode-parity/compareRules.d.ts +33 -0
- package/dist/types/dev/{fieldDiff.d.ts → mode-parity/fieldDiff.d.ts} +47 -5
- 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/new-sdk/execute/ExecuteApi.d.ts +9 -9
- package/dist/types/new-sdk/index.d.ts +4 -4
- package/dist/types/new-sdk/opportunities/OpportunitiesNamespace.d.ts +4 -4
- package/dist/types/new-sdk/opportunities/types.d.ts +5 -5
- package/dist/types/new-sdk/{simulate/SimulateApi.d.ts → prepare/PrepareApi.d.ts} +19 -19
- package/dist/types/new-sdk/prepare/index.d.ts +3 -0
- package/dist/types/new-sdk/{simulate → prepare}/types.d.ts +35 -61
- package/dist/types/sdk/accounts/intents/testing/sdk-mock.d.ts +1 -1
- package/dist/types/sdk/accounts/intents/types.d.ts +12 -12
- package/package.json +1 -1
- package/dist/cjs/dev/compareOpportunities.js +0 -137
- package/dist/cjs/new-sdk/simulate/index.js +0 -4
- package/dist/esm/new-sdk/simulate/index.js +0 -3
- package/dist/types/new-sdk/simulate/index.d.ts +0 -3
- /package/dist/cjs/new-sdk/{simulate → prepare}/types.js +0 -0
- /package/dist/esm/new-sdk/{simulate → prepare}/types.js +0 -0
|
@@ -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 };
|
|
@@ -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 };
|
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}
|
|
@@ -9,8 +9,8 @@ import "./errors/index.js";
|
|
|
9
9
|
import { AbstractNamespace } from "./AbstractNamespace.js";
|
|
10
10
|
import { ExecuteApi } from "./execute/ExecuteApi.js";
|
|
11
11
|
import "./execute/index.js";
|
|
12
|
-
import {
|
|
13
|
-
import "./
|
|
12
|
+
import { PrepareApi } from "./prepare/PrepareApi.js";
|
|
13
|
+
import "./prepare/index.js";
|
|
14
14
|
import { filterResponse } from "./utils/filterResponse.js";
|
|
15
15
|
import { DEFAULT_MAX_OFFCHAIN_LAG, mergeChainList, mergeChainOne } from "./utils/mergeChains.js";
|
|
16
16
|
import "./utils/index.js";
|
|
@@ -20,4 +20,4 @@ import { PositionsNamespace } from "./positions/PositionsNamespace.js";
|
|
|
20
20
|
import "./positions/index.js";
|
|
21
21
|
import { DEFAULT_MAX_STATE_AGE, GearboxSDK } from "./GearboxSDK.js";
|
|
22
22
|
import "./types.js";
|
|
23
|
-
export { AbstractNamespace, AllSourcesFailedError, DEFAULT_MAX_OFFCHAIN_LAG, DEFAULT_MAX_STATE_AGE, ExecuteApi, GearboxSDK, MissingSourceError, NoSourceServedError, OpportunitiesNamespace, PositionsNamespace,
|
|
23
|
+
export { AbstractNamespace, AllSourcesFailedError, DEFAULT_MAX_OFFCHAIN_LAG, DEFAULT_MAX_STATE_AGE, ExecuteApi, GearboxSDK, MissingSourceError, NoSourceServedError, OpportunitiesNamespace, PositionsNamespace, PrepareApi, SourceChainMismatchError, SourceUnavailableError, assertSameChains, everyChainFailed, filterResponse, mergeChainList, mergeChainOne };
|
|
@@ -5,8 +5,8 @@ import "../errors/index.js";
|
|
|
5
5
|
import { AbstractNamespace } from "../AbstractNamespace.js";
|
|
6
6
|
import { ExecuteApi } from "../execute/ExecuteApi.js";
|
|
7
7
|
import "../execute/index.js";
|
|
8
|
-
import {
|
|
9
|
-
import "../
|
|
8
|
+
import { PrepareApi } from "../prepare/PrepareApi.js";
|
|
9
|
+
import "../prepare/index.js";
|
|
10
10
|
import { filterResponse } from "../utils/filterResponse.js";
|
|
11
11
|
import { mergeChainList, mergeChainOne } from "../utils/mergeChains.js";
|
|
12
12
|
import "../utils/index.js";
|
|
@@ -24,19 +24,19 @@ var OpportunitiesNamespace = class extends AbstractNamespace {
|
|
|
24
24
|
pool: (onchain, offchain) => mergeChainOne(onchain, offchain, this.maxOffchainLagSeconds),
|
|
25
25
|
strategy: (onchain, offchain) => mergeChainOne(onchain, offchain, this.maxOffchainLagSeconds)
|
|
26
26
|
};
|
|
27
|
-
#
|
|
27
|
+
#prepare;
|
|
28
28
|
#execute;
|
|
29
29
|
constructor(onchain, offchain, options) {
|
|
30
30
|
super("Opportunities", onchain?.opportunities, offchain?.opportunities, options);
|
|
31
|
-
this.#
|
|
31
|
+
this.#prepare = onchain && new PrepareApi(onchain, options.ensureFresh);
|
|
32
32
|
this.#execute = onchain && new ExecuteApi((chainId) => onchain.chain(chainId));
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* {@inheritDoc OpportunitiesOnchainOnly.
|
|
35
|
+
* {@inheritDoc OpportunitiesOnchainOnly.prepare}
|
|
36
36
|
**/
|
|
37
|
-
get
|
|
38
|
-
if (!this.#
|
|
39
|
-
return this.#
|
|
37
|
+
get prepare() {
|
|
38
|
+
if (!this.#prepare) throw new SourceUnavailableError("Opportunities", "onchain");
|
|
39
|
+
return this.#prepare;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* {@inheritDoc OpportunitiesOnchainOnly.execute}
|
|
@@ -3,9 +3,9 @@ import { MultichainConstruct } from "../../sdk/base/MultichainConstruct.js";
|
|
|
3
3
|
import { fetchCreditAccountSlice } from "../../sdk/accounts/intents/utils/credit-account-slice.js";
|
|
4
4
|
import { CreditAccountOperationsService } from "../../sdk/accounts/intents/index.js";
|
|
5
5
|
import "../../sdk/index.js";
|
|
6
|
-
//#region src/new-sdk/
|
|
6
|
+
//#region src/new-sdk/prepare/PrepareApi.ts
|
|
7
7
|
/**
|
|
8
|
-
* {@inheritDoc
|
|
8
|
+
* {@inheritDoc OpportunitiesPrepare}
|
|
9
9
|
*
|
|
10
10
|
* Holds no state of its own: it owns the mapping from the public,
|
|
11
11
|
* read-model-shaped request to the engine's intent, and nothing else. All
|
|
@@ -17,7 +17,7 @@ import "../../sdk/index.js";
|
|
|
17
17
|
* to, hence a chain the SDK does not cover, or one that fails the read, throws
|
|
18
18
|
* rather than answering with empty metadata.
|
|
19
19
|
**/
|
|
20
|
-
var
|
|
20
|
+
var PrepareApi = class extends MultichainConstruct {
|
|
21
21
|
#ensureFresh;
|
|
22
22
|
constructor(sdk, ensureFresh) {
|
|
23
23
|
super(sdk);
|
|
@@ -28,22 +28,10 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
28
28
|
return super.queryChain(props);
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
* {@inheritDoc
|
|
31
|
+
* {@inheritDoc OpportunitiesPrepare.finalize}
|
|
32
32
|
**/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
type: "WITHDRAW",
|
|
36
|
-
amount: params.amount,
|
|
37
|
-
to: params.to,
|
|
38
|
-
tokenOut: params.tokenOut,
|
|
39
|
-
sourceToken: params.sourceToken
|
|
40
|
-
}),
|
|
41
|
-
adjustLeverage: (position, params) => this.#startDelayedIntent(position, params, {
|
|
42
|
-
type: "ADJUST_LEVERAGE",
|
|
43
|
-
targetLeverage: params.targetLeverage,
|
|
44
|
-
token: params.token
|
|
45
|
-
}),
|
|
46
|
-
finish: (position, params) => this.queryChain({
|
|
33
|
+
async finalize(position, params) {
|
|
34
|
+
return this.queryChain({
|
|
47
35
|
network: position.chainId,
|
|
48
36
|
run: async (sdk) => {
|
|
49
37
|
const intent = resumable(params.intent ?? params.claimable.intent);
|
|
@@ -60,10 +48,10 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
60
48
|
quotaReserve: params.quotaReserve
|
|
61
49
|
});
|
|
62
50
|
}
|
|
63
|
-
})
|
|
64
|
-
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
65
53
|
/**
|
|
66
|
-
* {@inheritDoc
|
|
54
|
+
* {@inheritDoc OpportunitiesPrepare.deposit}
|
|
67
55
|
**/
|
|
68
56
|
deposit(pool, params) {
|
|
69
57
|
const { marketRegister, pools } = this.sdk.chain(pool.chainId);
|
|
@@ -97,7 +85,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
97
85
|
};
|
|
98
86
|
}
|
|
99
87
|
/**
|
|
100
|
-
* {@inheritDoc
|
|
88
|
+
* {@inheritDoc OpportunitiesPrepare.withdraw}
|
|
101
89
|
**/
|
|
102
90
|
withdraw(pool, params) {
|
|
103
91
|
const { pools } = this.sdk.chain(pool.chainId);
|
|
@@ -129,7 +117,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
129
117
|
};
|
|
130
118
|
}
|
|
131
119
|
/**
|
|
132
|
-
* {@inheritDoc
|
|
120
|
+
* {@inheritDoc OpportunitiesPrepare.redeem}
|
|
133
121
|
**/
|
|
134
122
|
redeem(pool, params) {
|
|
135
123
|
const { pools } = this.sdk.chain(pool.chainId);
|
|
@@ -161,7 +149,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
161
149
|
};
|
|
162
150
|
}
|
|
163
151
|
/**
|
|
164
|
-
* {@inheritDoc
|
|
152
|
+
* {@inheritDoc OpportunitiesPrepare.openNewStrategy}
|
|
165
153
|
**/
|
|
166
154
|
async openNewStrategy(strategy, params) {
|
|
167
155
|
return this.queryChain({
|
|
@@ -179,7 +167,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
179
167
|
});
|
|
180
168
|
}
|
|
181
169
|
/**
|
|
182
|
-
* {@inheritDoc
|
|
170
|
+
* {@inheritDoc OpportunitiesPrepare.depositStrategy}
|
|
183
171
|
**/
|
|
184
172
|
async depositStrategy(position, params) {
|
|
185
173
|
return this.#startIntent(position, params, {
|
|
@@ -192,7 +180,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
192
180
|
});
|
|
193
181
|
}
|
|
194
182
|
/**
|
|
195
|
-
* {@inheritDoc
|
|
183
|
+
* {@inheritDoc OpportunitiesPrepare.withdrawStrategy}
|
|
196
184
|
**/
|
|
197
185
|
async withdrawStrategy(position, params) {
|
|
198
186
|
return this.#startRoutes(position, params, {
|
|
@@ -204,7 +192,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
204
192
|
});
|
|
205
193
|
}
|
|
206
194
|
/**
|
|
207
|
-
* {@inheritDoc
|
|
195
|
+
* {@inheritDoc OpportunitiesPrepare.maxWithdraw}
|
|
208
196
|
**/
|
|
209
197
|
async maxWithdraw(position) {
|
|
210
198
|
return this.queryChain({
|
|
@@ -216,7 +204,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
216
204
|
});
|
|
217
205
|
}
|
|
218
206
|
/**
|
|
219
|
-
* {@inheritDoc
|
|
207
|
+
* {@inheritDoc OpportunitiesPrepare.repayStrategy}
|
|
220
208
|
**/
|
|
221
209
|
async repayStrategy(position, params) {
|
|
222
210
|
return this.#startIntent(position, params, {
|
|
@@ -227,7 +215,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
227
215
|
});
|
|
228
216
|
}
|
|
229
217
|
/**
|
|
230
|
-
* {@inheritDoc
|
|
218
|
+
* {@inheritDoc OpportunitiesPrepare.maxRepay}
|
|
231
219
|
**/
|
|
232
220
|
async maxRepay(position) {
|
|
233
221
|
return this.queryChain({
|
|
@@ -239,7 +227,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
239
227
|
});
|
|
240
228
|
}
|
|
241
229
|
/**
|
|
242
|
-
* {@inheritDoc
|
|
230
|
+
* {@inheritDoc OpportunitiesPrepare.adjustLeverage}
|
|
243
231
|
**/
|
|
244
232
|
async adjustLeverage(position, params) {
|
|
245
233
|
return this.#startRoutes(position, params, {
|
|
@@ -249,7 +237,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
249
237
|
});
|
|
250
238
|
}
|
|
251
239
|
/**
|
|
252
|
-
* {@inheritDoc
|
|
240
|
+
* {@inheritDoc OpportunitiesPrepare.addCollateral}
|
|
253
241
|
**/
|
|
254
242
|
async addCollateral(position, params) {
|
|
255
243
|
return this.#startIntent(position, params, {
|
|
@@ -260,7 +248,7 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
260
248
|
});
|
|
261
249
|
}
|
|
262
250
|
/**
|
|
263
|
-
* {@inheritDoc
|
|
251
|
+
* {@inheritDoc OpportunitiesPrepare.withdrawCollateral}
|
|
264
252
|
**/
|
|
265
253
|
async withdrawCollateral(position, params) {
|
|
266
254
|
return this.#startIntent(position, params, {
|
|
@@ -287,22 +275,6 @@ var SimulateApi = class extends MultichainConstruct {
|
|
|
287
275
|
});
|
|
288
276
|
}
|
|
289
277
|
/**
|
|
290
|
-
* Shared path of the same two flows when only the delayed route is asked for:
|
|
291
|
-
* a planner that requests a redemption instead of swapping.
|
|
292
|
-
**/
|
|
293
|
-
async #startDelayedIntent(position, options, intent) {
|
|
294
|
-
return this.queryChain({
|
|
295
|
-
network: position.chainId,
|
|
296
|
-
run: async (sdk) => service(sdk).startDelayedIntent({
|
|
297
|
-
intent,
|
|
298
|
-
creditAccount: await slice(sdk, position.creditAccount),
|
|
299
|
-
sdk,
|
|
300
|
-
slippage: options.slippage,
|
|
301
|
-
quotaReserve: options.quotaReserve
|
|
302
|
-
})
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
278
|
* Shared path of the five flows that act on an existing account: read the
|
|
307
279
|
* account, then run the intent through the engine.
|
|
308
280
|
**/
|
|
@@ -357,4 +329,4 @@ function lpRoute(requested, routes) {
|
|
|
357
329
|
return options.length === 1 ? options[0] : void 0;
|
|
358
330
|
}
|
|
359
331
|
//#endregion
|
|
360
|
-
export {
|
|
332
|
+
export { PrepareApi };
|
|
@@ -1,10 +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
5
|
import { ChainCompareCounts, CompareCounts, DiffKind, DiffPathCount, ExpectedDiffReason, FieldDiff } from "./fieldDiff.js";
|
|
6
6
|
import { Address } from "viem";
|
|
7
|
-
//#region src/dev/compareOpportunities.d.ts
|
|
7
|
+
//#region src/dev/mode-parity/compareOpportunities.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* Enough of an opportunity to identify it in a report without carrying the
|
|
10
10
|
* whole row.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { ChainId } from "
|
|
2
|
-
import { Position, PositionId, PositionKind } from "
|
|
3
|
-
import { ChainMetadata, DataResponse } from "
|
|
4
|
-
import "
|
|
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
5
|
import { ChainCompareCounts, CompareCounts, DiffPathCount, FieldDiff } from "./fieldDiff.js";
|
|
6
6
|
import { Address } from "viem";
|
|
7
|
-
//#region src/dev/comparePositions.d.ts
|
|
7
|
+
//#region src/dev/mode-parity/comparePositions.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* Enough of a position to identify it in a report without carrying the whole
|
|
10
10
|
* row.
|
|
@@ -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 };
|