mirror of
https://github.com/Brotocol-xyz/bro-sdk.git
synced 2026-01-12 06:44:18 +08:00
feat(swapHelpers): add batchSize option to FetchRoutesImpl factories
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
"@stacks/stacks-blockchain-api-types": "^7.14.1",
|
||||
"@stacks/transactions": "^7.0.5",
|
||||
"@xlink-network/xlink-sdk": "file:../..",
|
||||
"alex-sdk": "github:alexgo-io/alex-sdk#feat/detailed-swap-route-info",
|
||||
"alex-sdk": "^3.2.0",
|
||||
"c32check": "^2.0.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"react": "^19.0.0",
|
||||
|
||||
11
examples/cross-chain-swap/pnpm-lock.yaml
generated
11
examples/cross-chain-swap/pnpm-lock.yaml
generated
@@ -27,8 +27,8 @@ importers:
|
||||
specifier: file:../..
|
||||
version: file:../..(@stacks/common@7.0.2)(typescript@5.8.2)
|
||||
alex-sdk:
|
||||
specifier: github:alexgo-io/alex-sdk#feat/detailed-swap-route-info
|
||||
version: https://codeload.github.com/alexgo-io/alex-sdk/tar.gz/15171aec2fec824ce3593982ba254748588c1303(@stacks/common@7.0.2)(@stacks/network@7.0.2)(@stacks/transactions@7.0.5)
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(@stacks/common@7.0.2)(@stacks/network@7.0.2)(@stacks/transactions@7.0.5)
|
||||
c32check:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
@@ -550,9 +550,8 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
alex-sdk@https://codeload.github.com/alexgo-io/alex-sdk/tar.gz/15171aec2fec824ce3593982ba254748588c1303:
|
||||
resolution: {tarball: https://codeload.github.com/alexgo-io/alex-sdk/tar.gz/15171aec2fec824ce3593982ba254748588c1303}
|
||||
version: 3.0.4
|
||||
alex-sdk@3.2.0:
|
||||
resolution: {integrity: sha512-5Y83pTK3T7wN/SzgFQdjddzYutUuarTsKV6Wt7l4j081RECMYteeiga320iR17MY4R7Jekkw+Rsb0KtvuGnO4Q==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@stacks/network': ^7.0.2
|
||||
@@ -1578,7 +1577,7 @@ snapshots:
|
||||
optionalDependencies:
|
||||
typescript: 5.8.2
|
||||
|
||||
alex-sdk@https://codeload.github.com/alexgo-io/alex-sdk/tar.gz/15171aec2fec824ce3593982ba254748588c1303(@stacks/common@7.0.2)(@stacks/network@7.0.2)(@stacks/transactions@7.0.5):
|
||||
alex-sdk@3.2.0(@stacks/common@7.0.2)(@stacks/network@7.0.2)(@stacks/transactions@7.0.5):
|
||||
dependencies:
|
||||
'@stacks/network': 7.0.2
|
||||
'@stacks/transactions': 7.0.5
|
||||
|
||||
@@ -7,23 +7,18 @@ import {
|
||||
XLinkSDK,
|
||||
} from "@xlink-network/xlink-sdk"
|
||||
import { AlexSDK } from "alex-sdk"
|
||||
import { FC, Fragment, useEffect, useState } from "react"
|
||||
import { FC, Fragment, useState } from "react"
|
||||
import { useQuery } from "react-query"
|
||||
import { useDebouncedValue } from "../hooks/useDebouncedValue"
|
||||
import { formatXLinkSDKChainName } from "../utils/formatXLinkSDKChainName"
|
||||
import { getAvailableRoutes } from "../utils/getAvailableRoutes"
|
||||
import { getSwapRoutesViaALEX } from "../utils/getSwapRoutesViaALEX"
|
||||
import { getSwapRoutesViaEVMDEX } from "../utils/getSwapRoutesViaEVMDEX"
|
||||
import { formatXLinkSDKChainName } from "../utils/formatXLinkSDKChainName"
|
||||
import { useDebouncedValue } from "../hooks/useDebouncedValue"
|
||||
|
||||
const STORAGE_KEY = "xlink_matcha_api_key"
|
||||
|
||||
export const SwapRouteSelector: FC<{
|
||||
alexSDK: AlexSDK
|
||||
xlinkSDK: XLinkSDK
|
||||
}> = ({ alexSDK, xlinkSDK }) => {
|
||||
const [matchaAPIKey, setMatchaAPIKey] = useState(() => {
|
||||
return localStorage.getItem(STORAGE_KEY) || ""
|
||||
})
|
||||
const [swapAmount, setSwapAmount] = useState("")
|
||||
const [selectedRoute, setSelectedRoute] = useState<null | KnownRoute>(null)
|
||||
const [selectedSwapRoute, setSelectedSwapRoute] =
|
||||
@@ -31,11 +26,6 @@ export const SwapRouteSelector: FC<{
|
||||
|
||||
const debouncedSwapAmount = useDebouncedValue(swapAmount, 500)
|
||||
const debouncedRoute = useDebouncedValue(selectedRoute, 500)
|
||||
const debouncedAPIKey = useDebouncedValue(matchaAPIKey, 500)
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem(STORAGE_KEY, matchaAPIKey)
|
||||
}, [matchaAPIKey])
|
||||
|
||||
const availableRoutes = useQuery({
|
||||
queryKey: ["availableRoutes"],
|
||||
@@ -72,7 +62,7 @@ export const SwapRouteSelector: FC<{
|
||||
})
|
||||
|
||||
const evmDexRoutes = useQuery({
|
||||
enabled: !!debouncedRoute && !!debouncedSwapAmount && !!debouncedAPIKey,
|
||||
enabled: !!debouncedRoute && !!debouncedSwapAmount,
|
||||
queryKey: [
|
||||
"evmDexRoutes",
|
||||
JSON.stringify(debouncedRoute),
|
||||
@@ -82,9 +72,6 @@ export const SwapRouteSelector: FC<{
|
||||
if (debouncedRoute == null) {
|
||||
throw new Error("No route selected")
|
||||
}
|
||||
if (!debouncedAPIKey) {
|
||||
throw new Error("No matcha API key")
|
||||
}
|
||||
if (!isNumber(debouncedSwapAmount)) {
|
||||
throw new Error("No swap amount")
|
||||
}
|
||||
@@ -92,7 +79,6 @@ export const SwapRouteSelector: FC<{
|
||||
return getSwapRoutesViaEVMDEX(
|
||||
{
|
||||
xlinkSDK: xlinkSDK,
|
||||
matchaAPIKey: debouncedAPIKey,
|
||||
},
|
||||
{
|
||||
...debouncedRoute,
|
||||
@@ -163,18 +149,6 @@ export const SwapRouteSelector: FC<{
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="section">
|
||||
<h2>Basic Information</h2>
|
||||
<div className="input-group">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Enter 0x API Key"
|
||||
value={matchaAPIKey}
|
||||
onChange={e => setMatchaAPIKey(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="section">
|
||||
<h2>Swap Settings</h2>
|
||||
<div className="swap-group">
|
||||
|
||||
@@ -7,15 +7,14 @@ import {
|
||||
XLinkSDK,
|
||||
} from "@xlink-network/xlink-sdk"
|
||||
import {
|
||||
fetchIceScreamSwapPossibleRoutesFactory,
|
||||
getDexAggregatorRoutes,
|
||||
getPossibleEVMDexAggregatorSwapParameters,
|
||||
fetchMatchaPossibleRoutesFactory,
|
||||
} from "@xlink-network/xlink-sdk/swapHelpers"
|
||||
|
||||
export async function getSwapRoutesViaEVMDEX(
|
||||
context: {
|
||||
xlinkSDK: XLinkSDK
|
||||
matchaAPIKey: string
|
||||
},
|
||||
swapRequest: KnownRoute & {
|
||||
amount: SDKNumber
|
||||
@@ -38,10 +37,7 @@ export async function getSwapRoutesViaEVMDEX(
|
||||
}
|
||||
|
||||
const routes = await getDexAggregatorRoutes(xlinkSDK, {
|
||||
routeFetcher: fetchMatchaPossibleRoutesFactory({
|
||||
baseUrl: "/api/matcha",
|
||||
apiKey: context.matchaAPIKey,
|
||||
}),
|
||||
routeFetcher: fetchIceScreamSwapPossibleRoutesFactory({}),
|
||||
routes: possibleSwapParameters.map(p => ({
|
||||
evmChain: p.evmChain,
|
||||
fromToken: p.fromToken,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { toSDKNumberOrUndefined } from "../../../xlinkSdkUtils/types"
|
||||
import { arraySplit } from "../../arrayHelpers"
|
||||
import { BigNumber } from "../../BigNumber"
|
||||
import { XLinkSDKErrorBase } from "../../errors"
|
||||
import { FetchRoutesImpl, QueryableRoute } from "./helpers"
|
||||
@@ -10,6 +11,12 @@ export class FetchIceScreamSwapPossibleRoutesFailedError extends XLinkSDKErrorBa
|
||||
}
|
||||
|
||||
export const fetchIceScreamSwapPossibleRoutesFactory = (options: {
|
||||
/**
|
||||
* The maximum number of routes to fetch in same time
|
||||
*
|
||||
* @default 1
|
||||
*/
|
||||
batchSize?: number
|
||||
baseUrl?: string
|
||||
debug?: boolean
|
||||
}): FetchRoutesImpl => {
|
||||
@@ -20,17 +27,26 @@ export const fetchIceScreamSwapPossibleRoutesFactory = (options: {
|
||||
|
||||
const baseUrl = options.baseUrl ?? "https://aggregator.icecreamswap.com"
|
||||
|
||||
const batchSize = options.batchSize ?? 1
|
||||
|
||||
return async info => {
|
||||
const res: Awaited<ReturnType<FetchRoutesImpl>> = []
|
||||
for (const route of info.possibleRoutes) {
|
||||
const batches = arraySplit(
|
||||
(_, idx) => Math.floor(idx / batchSize),
|
||||
info.possibleRoutes,
|
||||
)
|
||||
|
||||
const res: Awaited<ReturnType<FetchRoutesImpl>>[] = []
|
||||
for (const batch of batches) {
|
||||
res.push(
|
||||
...(await fetchIceScreamSwapPossibleRouteImpl(
|
||||
{ debugLog, baseUrl },
|
||||
route,
|
||||
...(await Promise.all(
|
||||
batch.map(route =>
|
||||
fetchIceScreamSwapPossibleRouteImpl({ debugLog, baseUrl }, route),
|
||||
),
|
||||
)),
|
||||
)
|
||||
}
|
||||
return res
|
||||
|
||||
return res.flat()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
import { toSDKNumberOrUndefined } from "../../../xlinkSdkUtils/types"
|
||||
import { arraySplit } from "../../arrayHelpers"
|
||||
import { BigNumber } from "../../BigNumber"
|
||||
import { XLinkSDKErrorBase } from "../../errors"
|
||||
import { FetchRoutesImpl, QueryableRoute } from "./helpers"
|
||||
|
||||
export class FetchMatchaPossibleRoutesFailedError extends XLinkSDKErrorBase {
|
||||
constructor(message: null | string, options: ErrorConstructorOptions) {
|
||||
super(message ?? "Request Matcha.xyz api failed", options)
|
||||
super(message ?? "Request 0x.org api failed", options)
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchMatchaPossibleRoutesFactory = (options: {
|
||||
apiKey: string
|
||||
/**
|
||||
* The maximum number of routes to fetch in same time
|
||||
*
|
||||
* @default 10 (0x.org api limit, see https://0x.org/docs/developer-resources/rate-limits#what-are-the-rate-limits-for-the-0x-apis)
|
||||
*/
|
||||
batchSize?: number
|
||||
baseUrl?: string
|
||||
debug?: boolean
|
||||
}): FetchRoutesImpl => {
|
||||
@@ -21,17 +28,29 @@ export const fetchMatchaPossibleRoutesFactory = (options: {
|
||||
|
||||
const baseUrl = options.baseUrl ?? "https://api.0x.org"
|
||||
|
||||
const batchSize = options.batchSize ?? 10
|
||||
|
||||
return async info => {
|
||||
const res: Awaited<ReturnType<FetchRoutesImpl>> = []
|
||||
for (const route of info.possibleRoutes) {
|
||||
const batches = arraySplit(
|
||||
(_, idx) => Math.floor(idx / batchSize),
|
||||
info.possibleRoutes,
|
||||
)
|
||||
|
||||
const res: Awaited<ReturnType<FetchRoutesImpl>>[] = []
|
||||
for (const batch of batches) {
|
||||
res.push(
|
||||
...(await fetchMatchaPossibleRouteImpl(
|
||||
{ apiKey: options.apiKey, baseUrl, debugLog },
|
||||
route,
|
||||
...(await Promise.all(
|
||||
batch.map(route =>
|
||||
fetchMatchaPossibleRouteImpl(
|
||||
{ debugLog, baseUrl, apiKey: options.apiKey },
|
||||
route,
|
||||
),
|
||||
),
|
||||
)),
|
||||
)
|
||||
}
|
||||
return res
|
||||
|
||||
return res.flat()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user