Skip to content

Commit 73e7c83

Browse files
committed
add providers to main strategies
1 parent 1e550f9 commit 73e7c83

File tree

12 files changed

+115
-28
lines changed

12 files changed

+115
-28
lines changed

src/api/routes/swap/swapModel.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ const swapApiResponseSwapSchema = z.object({
128128
description: "Swapper contract address",
129129
}),
130130
swapperData: hexSchema.openapi({
131-
description: "Already encodedd Swapper multicall payload",
131+
description: "Already encoded Swapper multicall payload",
132132
}),
133133
multicallItems: z
134134
.array(swapApiResponseMulticallItemSchema)
@@ -284,6 +284,15 @@ const getSwapSchema = z.object({
284284
.openapi({
285285
param: { description: "Optional override of the pipeline config" },
286286
}),
287+
provider: z
288+
.string()
289+
.optional()
290+
.openapi({
291+
param: {
292+
description:
293+
"Preselected provider of the quote. See `providers` endpoint",
294+
},
295+
}),
287296
}),
288297
})
289298

@@ -354,11 +363,9 @@ const getProvidersSchema = z.object({
354363
}),
355364
})
356365

357-
const providersResponseSchema = z
358-
.array(z.string())
359-
.openapi({
360-
description: "Array of providers for use with `swapWithProvider` endpoint",
361-
})
366+
const providersResponseSchema = z.array(z.string()).openapi({
367+
description: "Array of providers for use with `swapWithProvider` endpoint",
368+
})
362369

363370
export {
364371
getSwapSchema,

src/swapService/runner.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ import { strategies } from "./strategies/index"
1212
import type { StrategyResult, SwapParams } from "./types"
1313
import { ApiError, addInOutDeposits } from "./utils"
1414

15-
function loadPipeline(chainId: number, routingOverride?: ChainRoutingConfig) {
15+
// provider is needed in construction by balmy strategy which doesn't filter providers during the quote
16+
function loadPipeline(
17+
chainId: number,
18+
routingOverride?: ChainRoutingConfig,
19+
provider?: string,
20+
) {
1621
let routing: ChainRoutingConfig
1722
if (routingOverride) {
1823
routing = routingOverride
@@ -29,14 +34,19 @@ function loadPipeline(chainId: number, routingOverride?: ChainRoutingConfig) {
2934
return new strategies[routingItem.strategy](
3035
routingItem.match,
3136
routingItem.config,
37+
provider,
3238
)
3339
})
3440
}
3541

3642
export async function runPipeline(
3743
swapParams: SwapParams,
3844
): Promise<SwapApiResponse[]> {
39-
const pipeline = loadPipeline(swapParams.chainId, swapParams.routingOverride)
45+
const pipeline = loadPipeline(
46+
swapParams.chainId,
47+
swapParams.routingOverride,
48+
swapParams.provider,
49+
)
4050

4151
const allResults: StrategyResult[] = []
4252
for (const strategy of pipeline) {

src/swapService/strategies/strategyBalmySDK.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,37 @@ export class StrategyBalmySDK {
8686

8787
private readonly sdk
8888

89-
constructor(match = {}, config?: BalmyStrategyConfig) {
89+
constructor(match = {}, config?: BalmyStrategyConfig, provider?: string) {
9090
const allPendleAggregators = [
9191
...new Set(Object.values(pendleAggregators).flat()),
9292
]
9393

94-
if (config?.sourcesFilter?.includeSources?.includes("pendle")) {
95-
config.sourcesFilter.includeSources.push(
94+
let configClone = structuredClone(config)
95+
96+
if (configClone?.sourcesFilter?.includeSources?.includes("pendle")) {
97+
configClone.sourcesFilter.includeSources.push(
9698
...allPendleAggregators.map((aggregator) => `pendle-${aggregator}`),
9799
)
98-
config.sourcesFilter.includeSources =
99-
config.sourcesFilter.includeSources.filter((s) => s !== "pendle")
100+
configClone.sourcesFilter.includeSources =
101+
configClone.sourcesFilter.includeSources.filter((s) => s !== "pendle")
102+
}
103+
104+
if (provider) {
105+
if (!configClone) configClone = {} as BalmyStrategyConfig
106+
if (configClone.sourcesFilter?.excludeSources?.includes(provider)) {
107+
configClone.sourcesFilter = { includeSources: [] }
108+
} else {
109+
configClone.sourcesFilter = {
110+
includeSources: configClone.sourcesFilter?.includeSources
111+
? configClone.sourcesFilter.includeSources.filter(
112+
(s) => s === provider,
113+
)
114+
: [provider],
115+
}
116+
}
100117
}
101118

102-
this.config = { ...defaultConfig, ...(config || {}) }
119+
this.config = { ...defaultConfig, ...(configClone || {}) }
103120
const fetchService = buildFetchService()
104121
const providerService = buildProviderService({
105122
source: {
@@ -129,9 +146,6 @@ export class StrategyBalmySDK {
129146
"li-fi": {
130147
apiKey: String(process.env.LIFI_API_KEY),
131148
},
132-
// pendle: {
133-
// apiKey: String(process.env.PENDLE_API_KEY),
134-
// },
135149
"open-ocean": {
136150
apiKey: String(process.env.OPENOCEAN_API_KEY),
137151
},
@@ -195,7 +209,9 @@ export class StrategyBalmySDK {
195209
return (
196210
!isExactInRepay(swapParams) &&
197211
(this.sdk.quoteService.supportedChains().includes(swapParams.chainId) ||
198-
swapParams.chainId === 1923) // TODO fix!
212+
swapParams.chainId === 1923) && // TODO fix!
213+
(!this.config.sourcesFilter?.includeSources ||
214+
this.config.sourcesFilter.includeSources.length > 0)
199215
)
200216
}
201217

src/swapService/strategies/strategyCurveLPNG.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
buildApiResponseVerifyDebtMax,
1818
buildApiResponseVerifySkimMin,
1919
encodeSwapMulticallItem,
20+
includesCustomProvider,
2021
isExactInRepay,
2122
matchParams,
2223
} from "../utils"
@@ -66,6 +67,7 @@ export class StrategyCurveLPNG {
6667
async supports(swapParams: SwapParams) {
6768
return (
6869
!isExactInRepay(swapParams) &&
70+
includesCustomProvider(swapParams) && // strategy is not running the pipeline, only direct interactions
6971
this.config.supportedPools.some(
7072
(v) =>
7173
v.chainId === swapParams.chainId &&

src/swapService/strategies/strategyERC4626Wrapper.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
encodeSwapMulticallItem,
2222
encodeTargetDebtAsExactInMulticall,
2323
findToken,
24+
includesCustomProvider,
2425
isExactInRepay,
2526
matchParams,
2627
} from "../utils"
@@ -286,6 +287,11 @@ export class StrategyERC4626Wrapper {
286287

287288
if (!result.supports || !result.match) return result
288289

290+
if (this.isDirectSwap(swapParams) && !includesCustomProvider(swapParams)) {
291+
result.quotes = [] // this ends the pipeline and returns empty results
292+
return result
293+
}
294+
289295
try {
290296
switch (swapParams.swapperMode) {
291297
case SwapperMode.EXACT_IN: {
@@ -862,6 +868,19 @@ export class StrategyERC4626Wrapper {
862868

863869
return supportedVault
864870
}
871+
872+
isDirectSwap(swapParams: SwapParams) {
873+
return (
874+
this.isSupportedVaultUnderlying({
875+
vault: swapParams.tokenIn.address,
876+
underlying: swapParams.tokenOut.address,
877+
}) ||
878+
this.isSupportedVaultUnderlying({
879+
vault: swapParams.tokenOut.address,
880+
underlying: swapParams.tokenIn.address,
881+
})
882+
)
883+
}
865884
}
866885

867886
export async function encodeRedeem(

src/swapService/strategies/strategyElixir.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
encodeSwapMulticallItem,
2323
encodeTargetDebtAsExactInMulticall,
2424
findToken,
25+
includesCustomProvider,
2526
isExactInRepay,
2627
matchParams,
2728
} from "../utils"
@@ -91,6 +92,11 @@ export class StrategyElixir {
9192

9293
if (!result.supports || !result.match) return result
9394

95+
if (this.isDirectSwap(swapParams) && !includesCustomProvider(swapParams)) {
96+
result.quotes = [] // this ends the pipeline and returns empty results
97+
return result
98+
}
99+
94100
try {
95101
switch (swapParams.swapperMode) {
96102
case SwapperMode.EXACT_IN: {
@@ -668,6 +674,19 @@ export class StrategyElixir {
668674

669675
return supportedVault
670676
}
677+
678+
isDirectSwap(swapParams: SwapParams) {
679+
return (
680+
this.isSupportedVaultUnderlying({
681+
vault: swapParams.tokenIn.address,
682+
underlying: swapParams.tokenOut.address,
683+
}) ||
684+
this.isSupportedVaultUnderlying({
685+
vault: swapParams.tokenOut.address,
686+
underlying: swapParams.tokenIn.address,
687+
})
688+
)
689+
}
671690
}
672691

673692
export async function encodeRedeem(

src/swapService/strategies/strategyIdleCDOTranche.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
buildApiResponseVerifySkimMin,
1919
encodeSwapMulticallItem,
2020
findToken,
21+
includesCustomProvider,
2122
isExactInRepay,
2223
matchParams,
2324
} from "../utils"
@@ -103,8 +104,9 @@ export class StrategyIdleCDOTranche {
103104
underlying: swapParams.tokenIn.address,
104105
})
105106
) {
106-
result.quotes =
107-
await this.exactInFromUnderlyingToTranche(swapParams)
107+
result.quotes = includesCustomProvider(swapParams)
108+
? await this.exactInFromUnderlyingToTranche(swapParams)
109+
: []
108110
} else {
109111
result.quotes = await this.exactInFromAnyToTranche(swapParams)
110112
}

src/swapService/strategies/strategyMidas.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
encodeSwapMulticallItem,
2626
encodeTargetDebtAsExactInMulticall,
2727
findToken,
28+
includesCustomProvider,
2829
isExactInRepay,
2930
matchParams,
3031
} from "../utils"
@@ -232,17 +233,19 @@ export class StrategyMidas {
232233
if (
233234
isAddressEqual(swapParams.tokenOut.address, mToken.paymentToken)
234235
) {
235-
result.quotes =
236-
await this.exactInFromMTokenToPaymentToken(swapParams)
236+
result.quotes = includesCustomProvider(swapParams)
237+
? await this.exactInFromMTokenToPaymentToken(swapParams)
238+
: []
237239
} else {
238240
result.quotes = await this.exactInFromMTokenToAny(swapParams)
239241
}
240242
} else {
241243
if (
242244
isAddressEqual(swapParams.tokenIn.address, mToken.paymentToken)
243245
) {
244-
result.quotes =
245-
await this.exactInFromPaymentTokenToMToken(swapParams)
246+
result.quotes = includesCustomProvider(swapParams)
247+
? await this.exactInFromPaymentTokenToMToken(swapParams)
248+
: []
246249
} else {
247250
result.quotes = await this.exactInFromAnyToMToken(swapParams)
248251
}
@@ -254,17 +257,19 @@ export class StrategyMidas {
254257
if (
255258
isAddressEqual(swapParams.tokenOut.address, mToken.paymentToken)
256259
) {
257-
result.quotes =
258-
await this.targetDebtFromMTokenToPaymentToken(swapParams)
260+
result.quotes = includesCustomProvider(swapParams)
261+
? await this.targetDebtFromMTokenToPaymentToken(swapParams)
262+
: []
259263
} else {
260264
result.quotes = await this.targetDebtFromMTokenToAny(swapParams)
261265
}
262266
} else {
263267
if (
264268
isAddressEqual(swapParams.tokenIn.address, mToken.paymentToken)
265269
) {
266-
result.quotes =
267-
await this.targetDebtFromPaymentTokenToMToken(swapParams)
270+
result.quotes = includesCustomProvider(swapParams)
271+
? await this.targetDebtFromPaymentTokenToMToken(swapParams)
272+
: []
268273
} else {
269274
result.quotes = await this.targetDebtFromAnyToMToken(swapParams)
270275
}

src/swapService/strategies/strategyPendleCrossChainPT.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
encodeSwapMulticallItem,
2020
encodeTargetDebtAsExactInMulticall,
2121
findToken,
22+
includesCustomProvider,
2223
isExactInRepay,
2324
matchParams,
2425
} from "../utils"

src/swapService/strategies/strategyStrata.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
encodeSwapMulticallItem,
2222
encodeTargetDebtAsExactInMulticall,
2323
findToken,
24+
includesCustomProvider,
2425
isExactInRepay,
2526
matchParams,
2627
} from "../utils"

0 commit comments

Comments
 (0)