Skip to content

Commit 495ca6d

Browse files
committed
add ooga booga on bera
1 parent 6925e0b commit 495ca6d

File tree

12 files changed

+226
-2
lines changed

12 files changed

+226
-2
lines changed

.env.template

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ RPC_URL_80084=""
2323
# foundry
2424
RPC_URL_31337=""
2525
# sonic
26-
RPC_URL_146 s=""
26+
RPC_URL_146=""
27+
# bera
28+
RPC_URL_80094=""
2729

2830
# Provider API keys
2931
LIFI_API_KEY=""
@@ -34,4 +36,5 @@ OKX_API_KEY=""
3436
OKX_PASSPHRASE=""
3537
OKX_SECRET_KEY=""
3638
ODOS_API_KEY=""
37-
ODOS_REFERRAL_CODE=""
39+
ODOS_REFERRAL_CODE=""
40+
OOGABOOGA_API_KEY=""

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"dependencies": {
2727
"@asteasolutions/zod-to-openapi": "7.2.0",
2828
"@balmy/sdk": "0.6.8",
29+
"@berachain-foundation/berancer-sdk": "^0.33.2",
2930
"@uniswap/router-sdk": "1.15.0",
3031
"@uniswap/sdk-core": "6.1.1",
3132
"@uniswap/smart-order-router": "4.9.2",

pnpm-lock.yaml

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/common/utils/contractBook.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const contractBook: any = {
99
[chains.polygon.id]: "0x3e43F3CE1C364722df6470381Fa1F15ffbFB37E3",
1010
[1923]: "0x05Eb1A647265D974a1B0A57206048312604Ac6C3",
1111
[146]: "0xbAf5B12c92711a3657DD4adA6b3C7801e83Bb56a",
12+
[80094]: "0x4A35e6A872cf35623cd3fD07ebECEDFc0170D705",
1213
},
1314
},
1415
swapVerifier: {
@@ -19,6 +20,7 @@ const contractBook: any = {
1920
[chains.polygon.id]: "0x50C5ca05E916459F32c517932f1b4D78fb11018F",
2021
[1923]: "0x392C1570b3Bf29B113944b759cAa9a9282DA12Fe",
2122
[146]: "0x003ef4048b45a5A79D4499aaBd52108B3Bc9209f",
23+
[80094]: "0x6fFf8Ac4AB123B62FF5e92aBb9fF702DCBD6C939",
2224
},
2325
},
2426
}

src/common/utils/tokenList.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import tokenList1 from "../../tokenLists/tokenList_1"
33
import tokenList146 from "../../tokenLists/tokenList_146"
44
import tokenList1923 from "../../tokenLists/tokenList_1923"
55
import tokenList8453 from "../../tokenLists/tokenList_8543"
6+
import tokenList80094 from "../../tokenLists/tokenList_80094"
67

78
export type TokenListItem = {
89
addressInfo: Address
@@ -23,6 +24,7 @@ const cache: Record<number, TokenListItem[]> = {
2324
8453: tokenList8453 as TokenListItem[],
2425
1923: tokenList1923 as TokenListItem[],
2526
146: tokenList146 as TokenListItem[],
27+
80094: tokenList80094 as TokenListItem[],
2628
}
2729

2830
export default function getTokenList(chainId: number): TokenListItem[] {

src/common/utils/viemClients.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const RPC_URLS: Record<number, string> = {
3838
[chains.arbitrum.id]: process.env.RPC_URL_42161 || "",
3939
[chains.base.id]: process.env.RPC_URL_8453 || "",
4040
[bartio.id]: process.env.RPC_URL_80084 || "",
41+
[80094]: process.env.RPC_URL_80094 || "",
4142
[chains.foundry.id]: process.env.RPC_URL_31337 || "http://localhost:8545",
4243
} as const
4344

src/swapService/config/bera.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { type ChainRoutingConfig, SwapperMode } from "../interface"
2+
import { StrategyBalmySDK, StrategyRepayWrapper } from "../strategies"
3+
4+
const beraRoutingConfig: ChainRoutingConfig = [
5+
// WRAPPERS
6+
{
7+
strategy: StrategyRepayWrapper.name(),
8+
match: {
9+
isRepay: true,
10+
swapperModes: [SwapperMode.EXACT_IN],
11+
},
12+
},
13+
// DEFAULTS
14+
{
15+
strategy: StrategyBalmySDK.name(),
16+
config: {
17+
sourcesFilter: {
18+
includeSources: ["oogabooga"],
19+
},
20+
},
21+
match: {},
22+
},
23+
]
24+
25+
export default beraRoutingConfig

src/swapService/config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { base, mainnet } from "viem/chains"
22
import type { RoutingConfig } from "../interface"
33
import baseRoutingConfig from "./base"
4+
import beraRoutingConfig from "./bera"
45
import defaultRoutingConfig from "./default"
56
import mainnetRoutingConfig from "./mainnet"
67
import swellRoutingConfig from "./swell"
@@ -9,6 +10,7 @@ const routingConfig: RoutingConfig = {
910
[mainnet.id]: mainnetRoutingConfig,
1011
[base.id]: baseRoutingConfig,
1112
[1923]: swellRoutingConfig,
13+
[80094]: beraRoutingConfig,
1214
}
1315

1416
export const getRoutingConfig = (chainId: number) => {

src/swapService/strategies/balmySDK/customSourceList.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CustomLiFiQuoteSource } from "./lifiQuoteSource"
44
import { CustomNeptuneQuoteSource } from "./neptuneQuoteSource"
55
import { CustomOdosQuoteSource } from "./odosQuoteSource"
66
import { CustomOneInchQuoteSource } from "./oneInchQuoteSource"
7+
import { CustomOogaboogaQuoteSource } from "./oogaboogaQuoteSource"
78
import { CustomOpenOceanQuoteSource } from "./openOceanQuoteSource"
89
import { CustomPendleQuoteSource } from "./pendleQuoteSource"
910

@@ -19,6 +20,7 @@ const customSources = {
1920
"open-ocean": new CustomOpenOceanQuoteSource(),
2021
neptune: new CustomNeptuneQuoteSource(),
2122
odos: new CustomOdosQuoteSource(),
23+
oogabooga: new CustomOogaboogaQuoteSource(),
2224
}
2325
export class CustomSourceList extends LocalSourceList {
2426
constructor({ providerService, fetchService }: ConstructorParameters) {
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import type { ChainId } from "@balmy/sdk"
2+
import type {
3+
BuildTxParams,
4+
IQuoteSource,
5+
QuoteParams,
6+
QuoteSourceMetadata,
7+
SourceQuoteResponse,
8+
SourceQuoteTransaction,
9+
} from "@balmy/sdk/dist/services/quotes/quote-sources/types"
10+
import {
11+
addQuoteSlippage,
12+
calculateAllowanceTarget,
13+
failed,
14+
} from "@balmy/sdk/dist/services/quotes/quote-sources/utils"
15+
import qs from "qs"
16+
17+
const BERA_CHAIN_ID = 80094 as ChainId
18+
19+
export const OOGABOOGA_METADATA: QuoteSourceMetadata<OogaboogaSupport> = {
20+
name: "Ooga Booga",
21+
supports: {
22+
chains: [BERA_CHAIN_ID],
23+
swapAndTransfer: true,
24+
buyOrders: false,
25+
},
26+
logoURI: "",
27+
}
28+
29+
type OogaboogaSupport = { buyOrders: false; swapAndTransfer: true }
30+
type OogaboogaConfig = { apiKey: string }
31+
type OogaboogaData = { tx: SourceQuoteTransaction }
32+
export class CustomOogaboogaQuoteSource
33+
implements IQuoteSource<OogaboogaSupport, OogaboogaConfig, OogaboogaData>
34+
{
35+
getMetadata() {
36+
return OOGABOOGA_METADATA
37+
}
38+
39+
async quote(
40+
params: QuoteParams<OogaboogaSupport, OogaboogaConfig>,
41+
): Promise<SourceQuoteResponse<OogaboogaData>> {
42+
const { amountOut, to, data, value } = await this.getQuote(params)
43+
44+
const quote = {
45+
sellAmount: params.request.order.sellAmount,
46+
buyAmount: BigInt(amountOut),
47+
estimatedGas: undefined,
48+
allowanceTarget: calculateAllowanceTarget(params.request.sellToken, to),
49+
customData: {
50+
tx: {
51+
to,
52+
calldata: data,
53+
value: BigInt(value),
54+
},
55+
},
56+
}
57+
58+
return addQuoteSlippage(
59+
quote,
60+
params.request.order.type,
61+
params.request.config.slippagePercentage,
62+
)
63+
}
64+
65+
async buildTx({
66+
request,
67+
}: BuildTxParams<
68+
OogaboogaConfig,
69+
OogaboogaData
70+
>): Promise<SourceQuoteTransaction> {
71+
return request.customData.tx
72+
}
73+
74+
private async getQuote({
75+
components: { fetchService },
76+
request: {
77+
chainId,
78+
sellToken,
79+
buyToken,
80+
order,
81+
config: { slippagePercentage, timeout },
82+
accounts: { takeFrom, recipient },
83+
},
84+
config,
85+
}: QuoteParams<OogaboogaSupport, OogaboogaConfig>) {
86+
const queryParams = {
87+
tokenIn: sellToken,
88+
tokenOut: buyToken,
89+
amount: order.sellAmount.toString(),
90+
to: recipient ?? takeFrom,
91+
slippage: String(slippagePercentage / 100), // 1 = 100%
92+
}
93+
const queryString = qs.stringify(queryParams, {
94+
skipNulls: true,
95+
arrayFormat: "comma",
96+
})
97+
const url = `https://mainnet.api.oogabooga.io/v1/swap?${queryString}`
98+
const response = await fetchService.fetch(url, {
99+
timeout,
100+
headers: getHeaders(config),
101+
})
102+
if (!response.ok) {
103+
failed(
104+
OOGABOOGA_METADATA,
105+
chainId,
106+
sellToken,
107+
buyToken,
108+
(await response.text()) || `Failed with status ${response.status}`,
109+
)
110+
}
111+
112+
const {
113+
routerParams: {
114+
swapTokenInfo: { outputQuote: amountOut },
115+
},
116+
tx: { to, data, value },
117+
} = await response.json()
118+
return { amountOut, data, to, value }
119+
}
120+
121+
isConfigAndContextValidForQuoting(
122+
config: Partial<OogaboogaConfig> | undefined,
123+
): config is OogaboogaConfig {
124+
return !!config?.apiKey
125+
}
126+
127+
isConfigAndContextValidForTxBuilding(
128+
config: Partial<OogaboogaConfig> | undefined,
129+
): config is OogaboogaConfig {
130+
return !!config?.apiKey
131+
}
132+
}
133+
134+
function getHeaders(config: OogaboogaConfig) {
135+
const headers: Record<string, string> = {
136+
Authorization: `Bearer ${config.apiKey}`,
137+
}
138+
139+
return headers
140+
}

0 commit comments

Comments
 (0)