Skip to content

Commit 8fabf2b

Browse files
committed
add bob and oku
1 parent 3fdde20 commit 8fabf2b

File tree

8 files changed

+251
-0
lines changed

8 files changed

+251
-0
lines changed

.env.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ RPC_URL_146=""
2828
RPC_URL_80094=""
2929
# unichain
3030
RPC_URL_130=""
31+
# bob
32+
RPC_URL_60808=""
3133

3234
# Provider API keys
3335
LIFI_API_KEY=""

src/common/utils/contractBook.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const contractBook: any = {
1111
[146]: "0xbAf5B12c92711a3657DD4adA6b3C7801e83Bb56a",
1212
[80094]: "0x4A35e6A872cf35623cd3fD07ebECEDFc0170D705",
1313
[130]: "0x319E8ecd3BaB57fE684ca1aCfaB60c5603087B3A",
14+
[60808]: "0x697Ca30D765c1603890D88AAffBa3BeCCe72059d",
1415
},
1516
},
1617
swapVerifier: {
@@ -23,6 +24,7 @@ const contractBook: any = {
2324
[146]: "0x003ef4048b45a5A79D4499aaBd52108B3Bc9209f",
2425
[80094]: "0x6fFf8Ac4AB123B62FF5e92aBb9fF702DCBD6C939",
2526
[130]: "0x7eaf8C22480129E5D7426e3A33880D7bE19B50a7",
27+
[60808]: "0x296041DbdBC92171293F23c0a31e1574b791060d",
2628
},
2729
},
2830
}

src/swapService/config/bob.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 bobRoutingConfig: 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: ["oku_bob_icecreamswap", "oku_bob_uniswap"],
19+
},
20+
},
21+
match: {},
22+
},
23+
]
24+
25+
export default bobRoutingConfig

src/swapService/config/default.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const defaultRoutingConfig: ChainRoutingConfig = [
2424
"open-ocean",
2525
"uniswap",
2626
"0x",
27+
"oku",
2728
],
2829
},
2930
},

src/swapService/config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { base, mainnet } from "viem/chains"
22
import type { RoutingConfig } from "../interface"
33
import baseRoutingConfig from "./base"
44
import beraRoutingConfig from "./bera"
5+
import bobRoutingConfig from "./bob"
56
import defaultRoutingConfig from "./default"
67
import mainnetRoutingConfig from "./mainnet"
78
import swellRoutingConfig from "./swell"
@@ -11,6 +12,7 @@ const routingConfig: RoutingConfig = {
1112
[base.id]: baseRoutingConfig,
1213
[1923]: swellRoutingConfig,
1314
[80094]: beraRoutingConfig,
15+
[60808]: bobRoutingConfig,
1416
}
1517

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

src/swapService/strategies/balmySDK/customSourceList.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { LocalSourceList } from "@balmy/sdk/dist/services/quotes/source-lists/lo
33
import { CustomLiFiQuoteSource } from "./lifiQuoteSource"
44
import { CustomNeptuneQuoteSource } from "./neptuneQuoteSource"
55
import { CustomOdosQuoteSource } from "./odosQuoteSource"
6+
import { CustomOkuQuoteSource } from "./okuQuoteSource"
67
import { CustomOneInchQuoteSource } from "./oneInchQuoteSource"
78
import { CustomOogaboogaQuoteSource } from "./oogaboogaQuoteSource"
89
import { CustomOpenOceanQuoteSource } from "./openOceanQuoteSource"
@@ -23,6 +24,12 @@ const customSources = {
2324
odos: new CustomOdosQuoteSource(),
2425
oogabooga: new CustomOogaboogaQuoteSource(),
2526
uniswap: new CustomUniswapQuoteSource(),
27+
oku_bob_icecreamswap: new CustomOkuQuoteSource(
28+
"icecreamswap",
29+
"IceCreamSwap",
30+
[60808],
31+
),
32+
oku_bob_uniswap: new CustomOkuQuoteSource("usor", "Uniswap", [60808]),
2633
}
2734
export class CustomSourceList extends LocalSourceList {
2835
constructor({ providerService, fetchService }: ConstructorParameters) {
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import {
2+
type Address,
3+
Addresses,
4+
type ChainId,
5+
Chains,
6+
Contract,
7+
type GasPrice,
8+
type TimeString,
9+
type TokenAddress,
10+
calculateDeadline,
11+
getChainByKey,
12+
isSameAddress,
13+
} from "@balmy/sdk"
14+
import { AlwaysValidConfigAndContextSource } from "@balmy/sdk/dist/services/quotes/quote-sources/base/always-valid-source"
15+
import type {
16+
BuildTxParams,
17+
QuoteParams,
18+
QuoteSourceMetadata,
19+
SourceQuoteResponse,
20+
SourceQuoteTransaction,
21+
} from "@balmy/sdk/dist/services/quotes/quote-sources/types"
22+
import {
23+
addQuoteSlippage,
24+
calculateAllowanceTarget,
25+
failed,
26+
} from "@balmy/sdk/dist/services/quotes/quote-sources/utils"
27+
import { type Address as ViemAddress, formatUnits, parseUnits } from "viem"
28+
29+
const CHAINS: Record<ChainId, string> = {
30+
[60808]: "bob",
31+
}
32+
33+
const OKU_METADATA: QuoteSourceMetadata<OkuSupport> = {
34+
name: "Oku",
35+
supports: {
36+
chains: Object.keys(CHAINS).map(Number),
37+
swapAndTransfer: false,
38+
buyOrders: true,
39+
},
40+
logoURI: "ipfs://QmS2Kf7sZz7DrcwWU9nNG8eGt2126G2p2c9PTDFT774sW7",
41+
}
42+
43+
type OkuSupport = { buyOrders: true; swapAndTransfer: false }
44+
type OkuConfig = object
45+
type OkuData = {
46+
coupon: any
47+
signingRequest: any
48+
txValidFor: TimeString | undefined
49+
takeFrom: Address
50+
tx: SourceQuoteTransaction
51+
}
52+
53+
export class CustomOkuQuoteSource extends AlwaysValidConfigAndContextSource<
54+
OkuSupport,
55+
OkuConfig,
56+
OkuData
57+
> {
58+
private market: string
59+
private marketName: string
60+
private chains: number[] | undefined
61+
62+
constructor(market = "usor", marketName = "Uniswap", chains?: number[]) {
63+
super()
64+
this.market = market
65+
this.marketName = marketName
66+
this.chains = chains
67+
}
68+
getMetadata() {
69+
return {
70+
...OKU_METADATA,
71+
name: `${OKU_METADATA.name} ${this.marketName}`,
72+
supports: {
73+
...OKU_METADATA.supports,
74+
chains: this.chains || OKU_METADATA.supports.chains,
75+
},
76+
}
77+
}
78+
79+
async quote({
80+
components: { fetchService },
81+
request: {
82+
chainId,
83+
sellToken,
84+
buyToken,
85+
order,
86+
config: { slippagePercentage, timeout, txValidFor },
87+
accounts: { takeFrom },
88+
external,
89+
},
90+
}: QuoteParams<OkuSupport>): Promise<SourceQuoteResponse<OkuData>> {
91+
const chain = getChainByKey(chainId)
92+
if (
93+
chain &&
94+
isSameAddress(chain.wToken, sellToken) &&
95+
isSameAddress(Addresses.NATIVE_TOKEN, buyToken)
96+
)
97+
throw new Error("Native token wrap not supported by this source")
98+
if (
99+
chain &&
100+
isSameAddress(Addresses.NATIVE_TOKEN, sellToken) &&
101+
isSameAddress(chain.wToken, buyToken)
102+
)
103+
throw new Error("Native token wrap not supported by this source")
104+
105+
const [gasPrice, tokenData] = await Promise.all([
106+
external.gasPrice.request(),
107+
external.tokenData.request(),
108+
])
109+
const body = {
110+
chain: CHAINS[chainId],
111+
account: takeFrom,
112+
gasPrice: Number(eip1159ToLegacy(gasPrice)),
113+
isExactIn: order.type === "sell",
114+
inTokenAddress: mapToken(sellToken),
115+
outTokenAddress: mapToken(buyToken),
116+
slippage: slippagePercentage * 100,
117+
...(order.type === "sell"
118+
? {
119+
inTokenAmount: formatUnits(
120+
order.sellAmount,
121+
tokenData.sellToken.decimals,
122+
),
123+
}
124+
: {
125+
outTokenAmount: formatUnits(
126+
order.buyAmount,
127+
tokenData.buyToken.decimals,
128+
),
129+
}),
130+
}
131+
const quoteResponse = await fetchService.fetch(
132+
`https://canoe.v2.icarus.tools/market/${this.market}/swap_quote`,
133+
{
134+
method: "POST",
135+
body: JSON.stringify(body),
136+
headers: { "Content-Type": "application/json" },
137+
timeout,
138+
},
139+
)
140+
if (!quoteResponse.ok) {
141+
failed(
142+
OKU_METADATA,
143+
chainId,
144+
sellToken,
145+
buyToken,
146+
await quoteResponse.text(),
147+
)
148+
}
149+
const response = await quoteResponse.json()
150+
const { coupon, inAmount, outAmount, signingRequest } = response
151+
const sellAmount = parseUnits(inAmount, tokenData.sellToken.decimals)
152+
const buyAmount = parseUnits(outAmount, tokenData.buyToken.decimals)
153+
const to = coupon.raw.executionInformation.trade.to
154+
const quote = {
155+
sellAmount,
156+
buyAmount,
157+
type: order.type,
158+
allowanceTarget: calculateAllowanceTarget(sellToken, to),
159+
customData: {
160+
coupon,
161+
signingRequest,
162+
txValidFor,
163+
takeFrom,
164+
tx: {
165+
to,
166+
calldata: coupon.raw.executionInformation.trade.data,
167+
value: coupon.raw.executionInformation.trade.value,
168+
},
169+
},
170+
}
171+
return addQuoteSlippage(quote, order.type, slippagePercentage)
172+
}
173+
174+
async buildTx({
175+
request,
176+
}: BuildTxParams<OkuConfig, OkuData>): Promise<SourceQuoteTransaction> {
177+
return request.customData.tx
178+
}
179+
}
180+
181+
function mapToken(address: TokenAddress) {
182+
return isSameAddress(address, Addresses.NATIVE_TOKEN)
183+
? Addresses.ZERO_ADDRESS
184+
: (address as ViemAddress)
185+
}
186+
187+
function eip1159ToLegacy(gasPrice: GasPrice): bigint {
188+
if ("gasPrice" in gasPrice) {
189+
return BigInt(gasPrice.gasPrice)
190+
}
191+
return BigInt(gasPrice.maxFeePerGas)
192+
}

tokenLists/tokenList_60808.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"addressInfo": "0x03C7054BCB39f7b2e5B2c7AcB37583e32D70Cfa3",
4+
"chainId": 60808,
5+
"name": "WBTC",
6+
"symbol": "WBTC",
7+
"decimals": 8,
8+
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png",
9+
"meta": {}
10+
},
11+
{
12+
"addressInfo": "0xA45d4121b3D47719FF57a947A9d961539Ba33204",
13+
"chainId": 60808,
14+
"name": "LBTC",
15+
"symbol": "LBTC",
16+
"decimals": 8,
17+
"logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png",
18+
"meta": {}
19+
}
20+
]

0 commit comments

Comments
 (0)