Skip to content

Commit 0883575

Browse files
authored
[simplex,sdk]: support cross-chain fx, optimize gas estimation (#696)
1 parent 88c507c commit 0883575

File tree

12 files changed

+797
-1037
lines changed

12 files changed

+797
-1037
lines changed

docs/content/developers/evm/filler.mdx

Lines changed: 0 additions & 801 deletions
This file was deleted.

docs/content/developers/intent-gateway/simplex.mdx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ BasicFiller requires pre-positioned stablecoins on each destination chain.
5050

5151
### HyperFX
5252

53-
HyperFX fills same-chain swaps between USD-pegged stablecoins (USDC/USDT) and a single configurable exotic token — for example, cNGN (a Nigerian naira stablecoin). It only processes orders where `source == destination`.
53+
HyperFX fills swaps between USD-pegged stablecoins (USDC/USDT) and a single configurable exotic token — for example, cNGN (a Nigerian naira stablecoin). It supports both **same-chain** and **cross-chain** orders.
54+
55+
Same-chain orders (`source == destination`) are filled immediately without waiting for additional confirmations. Cross-chain orders use the configured **confirmation policy** for HyperFX to determine how many confirmations to wait for before bidding.
5456

5557
Profit comes from two sources: the **bid/ask spread** on the exotic token, and **order fees** minus gas. The filler holds both stablecoins and the exotic token. When a user swaps stable→exotic the filler sells exotic at the ask price; when the user swaps exotic→stable the filler buys at the bid price. The spread between the two curves is the filler's margin per trade.
5658

@@ -135,10 +137,10 @@ bundlerUrl = "https://api.pimlico.io/v2/56/rpc?apikey=YOUR_KEY"
135137
### Confirmation Policy
136138

137139
<Callout type="info">
138-
Confirmation policies only apply to BasicFiller. HyperFX submits bids via the coprocessor and does not use this setting.
140+
Confirmation policies are configured per strategy. Both BasicFiller and HyperFX can use confirmation policies for cross-chain orders.
139141
</Callout>
140142

141-
Before processing an order, Simplex waits for enough block confirmations to guard against chain reorganizations. The number of confirmations scales with order value using a curve — small orders are processed quickly, large orders wait longer:
143+
Before processing a cross-chain order, Simplex waits for enough block confirmations to guard against chain reorganizations. The number of confirmations scales with order value using a curve — small orders are processed quickly, large orders wait longer. Same-chain orders always proceed without additional confirmation delay.
142144

143145
```toml lineNumbers
144146
[confirmationPolicies."1"] # Ethereum Mainnet (~12s blocks)
@@ -163,6 +165,38 @@ points = [
163165
]
164166
```
165167

168+
For HyperFX, you can configure confirmation policies in the same way. For example:
169+
170+
```toml lineNumbers
171+
[[strategies]]
172+
type = "hyperfx"
173+
maxOrderUsd = "5000"
174+
175+
[strategies.exoticTokenAddresses]
176+
"EVM-56" = "0xExoticTokenAddressOnBsc"
177+
"EVM-137" = "0xExoticTokenAddressOnPolygon"
178+
179+
[strategies.confirmationPolicies]
180+
# Chain IDs for HyperFX confirmation policy (same schema as BasicFiller)
181+
[strategies.confirmationPolicies."56"] # BSC (~1s blocks)
182+
points = [
183+
{ amount = "1", value = 3 },
184+
{ amount = "500", value = 6 },
185+
{ amount = "5000", value = 15 },
186+
]
187+
188+
[strategies.confirmationPolicies."42161"] # Arbitrum (~0.25s blocks)
189+
points = [
190+
{ amount = "2", value = 2 },
191+
{ amount = "1000", value = 5 },
192+
{ amount = "8000", value = 10 },
193+
]
194+
```
195+
196+
<Callout type="warning">
197+
If HyperFX is configured without <code>[strategies.confirmationPolicies]</code>, Simplex logs a warning at startup and skips cross-chain orders for that strategy. Only same-chain HyperFX orders will be processed in that case.
198+
</Callout>
199+
166200
### Auto-Rebalancing
167201

168202
<Callout type="info">

sdk/packages/sdk/src/protocols/intents/CryptoUtils.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,45 @@ export class CryptoUtils {
309309
return result.result
310310
}
311311

312+
/**
313+
* Sends multiple JSON-RPC requests to the bundler in a single HTTP call
314+
* using JSON-RPC 2.0 batch syntax. Results are returned in the same order
315+
* as the input `requests` array.
316+
*
317+
* @throws If the bundler URL is not configured, the HTTP call fails, or any
318+
* individual response contains an error.
319+
*/
320+
async sendBundlerBatch<T extends unknown[]>(
321+
requests: { method: BundlerMethod; params: unknown[] }[],
322+
): Promise<T> {
323+
if (!this.ctx.bundlerUrl) {
324+
throw new Error("Bundler URL not configured")
325+
}
326+
327+
const body = requests.map((r, i) => ({
328+
jsonrpc: "2.0" as const,
329+
id: i + 1,
330+
method: r.method,
331+
params: r.params,
332+
}))
333+
334+
const response = await fetch(this.ctx.bundlerUrl, {
335+
method: "POST",
336+
headers: { "Content-Type": "application/json" },
337+
body: JSON.stringify(body),
338+
})
339+
340+
const results = (await response.json()) as { id: number; result?: unknown; error?: { message?: string } }[]
341+
results.sort((a, b) => a.id - b.id)
342+
343+
return results.map((r) => {
344+
if (r.error) {
345+
throw new Error(`Bundler error: ${r.error.message || JSON.stringify(r.error)}`)
346+
}
347+
return r.result
348+
}) as T
349+
}
350+
312351
/**
313352
* Encodes a list of calls into ERC-7821 `execute` calldata using
314353
* single-batch mode (`ERC7821_BATCH_MODE`).

0 commit comments

Comments
 (0)