@hyperbridge/simplex 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -151
- package/dist/bin/simplex.js +7769 -1943
- package/dist/bin/simplex.js.map +1 -1
- package/dist/error-reporting.cjs +123 -0
- package/dist/error-reporting.cjs.map +1 -0
- package/dist/error-reporting.d.cts +46 -0
- package/dist/error-reporting.d.ts +46 -0
- package/dist/error-reporting.js +95 -0
- package/dist/error-reporting.js.map +1 -0
- package/dist/index.cjs +1364 -557
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +311 -1896
- package/dist/index.d.ts +311 -1896
- package/dist/index.js +1362 -523
- package/dist/index.js.map +1 -1
- package/dist/sqlite.cjs +1 -0
- package/dist/sqlite.cjs.map +1 -1
- package/dist/sqlite.d.cts +7 -1
- package/dist/sqlite.d.ts +7 -1
- package/dist/sqlite.js +1 -0
- package/dist/sqlite.js.map +1 -1
- package/dist/types-6MEltdkX.d.cts +2297 -0
- package/dist/types-6MEltdkX.d.ts +2297 -0
- package/dist/ui/assets/bridge-BB9cnjYo.png +0 -0
- package/dist/ui/assets/hyperbridge-B8MVl-Oj.png +0 -0
- package/dist/ui/assets/index-DWJcHNgO.css +1 -0
- package/dist/ui/assets/index-Dy5dPCr_.js +2168 -0
- package/dist/ui/assets/usdr-gm4f6KeA.png +0 -0
- package/dist/ui/index.html +2 -2
- package/package.json +19 -4
- package/dist/types-BPyUX8qu.d.cts +0 -663
- package/dist/types-BPyUX8qu.d.ts +0 -663
- package/dist/ui/assets/index-CK8E6aPx.css +0 -1
- package/dist/ui/assets/index-D8DLeEH0.js +0 -106
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { EventEmitter
|
|
2
|
-
import { HexString, ERC7821Call,
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
import { ChannelCredentials } from '@grpc/grpc-js';
|
|
8
|
-
import { EventEmitter } from 'events';
|
|
9
|
-
import Decimal$1, { Decimal } from 'decimal.js';
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { HexString, ERC7821Call, IntentsCoprocessor, Order, TokenInfo, ChainConfig, ExecutionResult, IntentGateway, FillOptions, FillerConfig } from '@hyperbridge/sdk';
|
|
3
|
+
import { S as SignerConfig, a as Signer, b as Signature, D as DerivingSigner, c as SecretPhraseSignerConfig, M as MpcVaultSignerConfig, T as TurnkeySignerConfig, C as ChainClientManager, F as FillerConfigService, U as UserOpSender, L as LoggerContext, A as ActivityStore, d as ActivityInsert, e as ActivityEvent, O as OrderHistoryPage, W as WalletTx, f as LimitOrderStore, g as AssetRegistry, h as DelegationService, i as LimitOrder, j as LimitOrderFilter, B as BidStore, k as SimplexDataStore, l as ConfirmationPolicy, R as ResolvedChainConfig, m as FillerTomlConfig, V as VaultToml, n as TokenSender, o as BridgeTopUp, p as AssetDefinition, q as ChainConfirmationPolicy, r as LimitOrderFill, s as StoredBid, t as RebalancingConfig, u as LogSink, v as BidStats, w as AllowlistConfig, x as LogLevel, y as StateStore, I as InventoryStore } from './types-6MEltdkX.js';
|
|
4
|
+
export { z as ActivityType, E as AuthorizationRequest, G as BidInsert, H as BinanceConfig, J as CurveConfig, K as CurvePoint, N as Eip7702Authorization, P as FillerConfigFile, Q as InventorySnapshot, X as LimitOrderFillInsert, Y as LimitOrderFillRecord, Z as LimitOrderHold, _ as LimitOrderInsert, $ as LimitOrderPosting, a0 as LimitOrderSide, a1 as LimitOrderStatus, a2 as Logger, a3 as OperatorNotification, a4 as PrivateKeySignerConfig, a5 as QueueConfig, a6 as RuntimeState, a7 as SignerTransaction, a8 as SignerType, a9 as TypedDataPayload, aa as USD_STABLE_SYMBOLS, ab as UserProvidedChainConfig, ac as VaultTomlConfig, ad as WalletTxKind, ae as addLogSink, af as assertConfirmationCoverage, ag as configureLogger, ah as formatChainKey, ai as getLogger, aj as isRegistrySymbol, ak as normalizeSymbol, al as parseChainKey, am as registrySymbols, an as validateAssetDefinitions, ao as validateConfig, ap as validateVaultToml } from './types-6MEltdkX.js';
|
|
5
|
+
import { EventEmitter as EventEmitter$1 } from 'events';
|
|
6
|
+
import { Decimal } from 'decimal.js';
|
|
10
7
|
import * as _circle_fin_bridge_kit from '@circle-fin/bridge-kit';
|
|
11
8
|
import { BridgeResult, EstimateResult } from '@circle-fin/bridge-kit';
|
|
9
|
+
import { LocalAccount } from 'viem/accounts';
|
|
10
|
+
import 'viem';
|
|
12
11
|
import 'pino';
|
|
12
|
+
import '@grpc/grpc-js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* A liquidity source that can atomically withdraw tokens and make them
|
|
@@ -102,626 +102,6 @@ interface VaultOutputFundingConfig {
|
|
|
102
102
|
sweepIntervalMs?: number;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
interface UserProvidedChainConfig {
|
|
106
|
-
/** One or more RPC URLs. When multiple are provided, event scans use quorum consensus. */
|
|
107
|
-
rpcUrls: string[];
|
|
108
|
-
bundlerUrl: string;
|
|
109
|
-
}
|
|
110
|
-
interface ResolvedChainConfig {
|
|
111
|
-
chainId: number;
|
|
112
|
-
/** One or more RPC URLs for this chain. When multiple are provided, event scans use quorum consensus. */
|
|
113
|
-
rpcUrls: string[];
|
|
114
|
-
bundlerUrl?: string;
|
|
115
|
-
}
|
|
116
|
-
interface GasFeeBumpConfig {
|
|
117
|
-
maxPriorityFeePerGasBumpPercent?: number;
|
|
118
|
-
maxFeePerGasBumpPercent?: number;
|
|
119
|
-
}
|
|
120
|
-
interface RebalancingConfig$1 {
|
|
121
|
-
triggerPercentage: number;
|
|
122
|
-
baseBalances: {
|
|
123
|
-
USDC?: Record<string, string>;
|
|
124
|
-
USDT?: Record<string, string>;
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
interface OverfillProtectionConfig {
|
|
128
|
-
/** Ceiling bps above user-requested output; filler clamps its computed output to this. Default 500 (5%). */
|
|
129
|
-
maxOverfillBps?: number;
|
|
130
|
-
/** Consecutive clamped evaluations before the strategy halts itself. Default 3. */
|
|
131
|
-
maxConsecutiveClamps?: number;
|
|
132
|
-
}
|
|
133
|
-
interface AllowlistConfig {
|
|
134
|
-
/** Hex addresses eligible across all chains. */
|
|
135
|
-
users?: string[];
|
|
136
|
-
/** Per-source-chain overrides, keyed by state machine id (e.g. "EVM-1"). Merged with the global list. */
|
|
137
|
-
bySource?: Record<string, string[]>;
|
|
138
|
-
}
|
|
139
|
-
interface FillerConfig {
|
|
140
|
-
maxConcurrentOrders: number;
|
|
141
|
-
logging?: LogLevel;
|
|
142
|
-
hyperbridgeWsUrl?: string;
|
|
143
|
-
substratePrivateKey?: string;
|
|
144
|
-
entryPointAddress?: string;
|
|
145
|
-
/**
|
|
146
|
-
* Optional gas fee bump configuration for UserOperation gas estimation.
|
|
147
|
-
* If not provided, defaults will be used (8% for priority fee, 10% for max fee).
|
|
148
|
-
*/
|
|
149
|
-
gasFeeBump?: GasFeeBumpConfig;
|
|
150
|
-
rebalancing?: RebalancingConfig$1;
|
|
151
|
-
/**
|
|
152
|
-
* Target gas units the EntryPoint deposit should cover per chain.
|
|
153
|
-
* Defaults to 3,000,000 if not set.
|
|
154
|
-
*/
|
|
155
|
-
targetGasUnits?: number;
|
|
156
|
-
/**
|
|
157
|
-
* Seconds a signed bid stays executable. Defaults to 300 (5 minutes).
|
|
158
|
-
* See `bidValiditySeconds` in filler-toml for why this bound matters.
|
|
159
|
-
*/
|
|
160
|
-
bidValiditySeconds?: number;
|
|
161
|
-
/**
|
|
162
|
-
* Order size in USD below which `order.fees` must cover the execution cost.
|
|
163
|
-
* Defaults to 20. See `minOrderSizeUsd` in filler-toml.
|
|
164
|
-
*/
|
|
165
|
-
minOrderSizeUsd?: number;
|
|
166
|
-
/**
|
|
167
|
-
* Overfill protection knobs. If omitted, defaults are used
|
|
168
|
-
* (maxOverfillBps=500, maxConsecutiveClamps=3).
|
|
169
|
-
*/
|
|
170
|
-
overfillProtection?: OverfillProtectionConfig;
|
|
171
|
-
/**
|
|
172
|
-
* Restricts which order `user` addresses the filler processes. When omitted, all
|
|
173
|
-
* users are accepted. When present, only listed users (global ∪ per-source) are
|
|
174
|
-
* accepted; a chain whose merged set is empty rejects every order.
|
|
175
|
-
*/
|
|
176
|
-
allowlist?: AllowlistConfig;
|
|
177
|
-
/**
|
|
178
|
-
* How often the block scanner polls each chain, in seconds. Defaults to 3.
|
|
179
|
-
* Each tick costs one `eth_blockNumber` plus one `eth_getLogs` per chain per
|
|
180
|
-
* endpoint, so raising it is the main lever for staying inside a
|
|
181
|
-
* rate-limited RPC's budget — at the cost of seeing orders that much later.
|
|
182
|
-
*/
|
|
183
|
-
blockScanIntervalSeconds?: number;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Simplified configuration service for the filler that wraps ChainConfigService
|
|
187
|
-
* and only requires minimal user configuration (RPC URLs, private keys, etc.)
|
|
188
|
-
*/
|
|
189
|
-
declare class FillerConfigService {
|
|
190
|
-
/**
|
|
191
|
-
* This filler's logging destination. Services resolve their module loggers
|
|
192
|
-
* from here rather than from the process-wide context, which is what keeps
|
|
193
|
-
* two fillers in one process from writing into each other's sinks.
|
|
194
|
-
*/
|
|
195
|
-
readonly loggers: LoggerContext;
|
|
196
|
-
private chainConfigService;
|
|
197
|
-
private rpcOverrides;
|
|
198
|
-
private bundlerUrls;
|
|
199
|
-
private fillerConfig?;
|
|
200
|
-
/** Lowercased global allowlist users, or undefined when no global list is configured. */
|
|
201
|
-
private allowlistGlobal?;
|
|
202
|
-
/** Lowercased per-source allowlist users keyed by state machine id, or undefined when no per-source list is configured. */
|
|
203
|
-
private allowlistBySource?;
|
|
204
|
-
constructor(chainConfigs: ResolvedChainConfig[], fillerConfig?: FillerConfig, loggers?: LoggerContext);
|
|
205
|
-
getAllowlist(): AllowlistConfig | undefined;
|
|
206
|
-
/**
|
|
207
|
-
* Registers a chain at runtime. `getConfiguredChainIds` derives from the RPC
|
|
208
|
-
* override map, so this is what makes a chain "configured" — every address
|
|
209
|
-
* lookup already resolves through the SDK's chain registry, which knows the
|
|
210
|
-
* chain whether or not this filler was started with it.
|
|
211
|
-
*
|
|
212
|
-
* Rejects a chain that is already registered: silently replacing its
|
|
213
|
-
* endpoints would leave the event monitor scanning the old ones. Use
|
|
214
|
-
* {@link setRpcUrls} for that.
|
|
215
|
-
*/
|
|
216
|
-
addChain(chain: ResolvedChainConfig): void;
|
|
217
|
-
/** Drops a chain from the configured set. */
|
|
218
|
-
removeChain(chainId: number): void;
|
|
219
|
-
/**
|
|
220
|
-
* Replaces a chain's RPC endpoints. Callers must invalidate the cached viem
|
|
221
|
-
* clients (`ChainClientManager.invalidate`) and rebuild the chain's scanner
|
|
222
|
-
* afterwards — a client bakes its transport in at construction, so this
|
|
223
|
-
* change is invisible to anything already holding one.
|
|
224
|
-
*/
|
|
225
|
-
setRpcUrls(chainId: number, rpcUrls: string[]): void;
|
|
226
|
-
setBundlerUrl(chainId: number, bundlerUrl: string): void;
|
|
227
|
-
/** Replaces the rebalancing config at runtime; trigger checks read it live. */
|
|
228
|
-
setRebalancing(rebalancing: RebalancingConfig$1 | undefined): void;
|
|
229
|
-
/** Replaces the allowlist at runtime; takes effect on the next order. */
|
|
230
|
-
setAllowlist(allowlist: AllowlistConfig | undefined): void;
|
|
231
|
-
/**
|
|
232
|
-
* Whether an order from `user` on `chain` (a source state machine id, e.g. "EVM-1")
|
|
233
|
-
* may be processed. Returns true when no allowlist is configured. Otherwise the user
|
|
234
|
-
* must appear in the global list or the per-source override for that chain; an empty
|
|
235
|
-
* merged set rejects every order on that chain.
|
|
236
|
-
*/
|
|
237
|
-
isUserAllowed(user: string, chain: string): boolean;
|
|
238
|
-
getChainConfig(chain: string): ChainConfig;
|
|
239
|
-
getIntentGatewayAddress(chain: string): `0x${string}`;
|
|
240
|
-
getHostAddress(chain: string): `0x${string}`;
|
|
241
|
-
getWrappedNativeAssetWithDecimals(chain: string): {
|
|
242
|
-
asset: HexString;
|
|
243
|
-
decimals: number;
|
|
244
|
-
};
|
|
245
|
-
getDaiAsset(chain: string): HexString;
|
|
246
|
-
getUsdtAsset(chain: string): HexString;
|
|
247
|
-
getUsdcAsset(chain: string): HexString;
|
|
248
|
-
getUsdcDecimals(chain: string): number;
|
|
249
|
-
getSimplexPaymasterAddress(chain: string): HexString | undefined;
|
|
250
|
-
getUsdtDecimals(chain: string): number;
|
|
251
|
-
/**
|
|
252
|
-
* Curated decimals for a token, looked up by address in the SDK's per-chain
|
|
253
|
-
* asset table. Returns `undefined` for any token not in that table.
|
|
254
|
-
*
|
|
255
|
-
* This is the safety net for `ContractInteractionService.getTokenDecimals`
|
|
256
|
-
* when the on-chain `decimals()` read fails: the registry already carries the
|
|
257
|
-
* correct value for every supported asset (verified on-chain at curation
|
|
258
|
-
* time), so a failed read has no business guessing.
|
|
259
|
-
*/
|
|
260
|
-
getAssetDecimalsByAddress(chain: string, address: HexString): number | undefined;
|
|
261
|
-
getChainId(chain: string): number;
|
|
262
|
-
getConsensusStateId(chain: string): string;
|
|
263
|
-
getHyperbridgeChainId(): number;
|
|
264
|
-
getHyperbridgeRpcUrl(): string;
|
|
265
|
-
getRpcUrl(chain: string): string;
|
|
266
|
-
/**
|
|
267
|
-
* Returns every user-configured RPC URL for a chain. When multiple URLs are present,
|
|
268
|
-
* consumers (e.g. the event monitor) run queries as a quorum — every provider must
|
|
269
|
-
* return the same result for the batch to succeed.
|
|
270
|
-
*/
|
|
271
|
-
getRpcUrls(chain: string): string[];
|
|
272
|
-
private getChainIdFromStateMachineId;
|
|
273
|
-
getUniswapRouterV2Address(chain: string): HexString;
|
|
274
|
-
getUniswapV2FactoryAddress(chain: string): HexString;
|
|
275
|
-
getUniversalRouterAddress(chain: string): HexString;
|
|
276
|
-
getUniswapV3QuoterAddress(chain: string): HexString;
|
|
277
|
-
getUniswapV4QuoterAddress(chain: string): HexString;
|
|
278
|
-
getUniswapV4PositionManagerAddress(chain: string): HexString;
|
|
279
|
-
getUniswapV4PoolManagerAddress(chain: string): HexString;
|
|
280
|
-
getUniswapV4StateViewAddress(chain: string): HexString;
|
|
281
|
-
getPermit2Address(chain: string): HexString;
|
|
282
|
-
getCoingeckoId(chain: string): string | undefined;
|
|
283
|
-
getCNgnAsset(chain: string): HexString | undefined;
|
|
284
|
-
getAssetBySymbol(chain: string, symbol: string): HexString | undefined;
|
|
285
|
-
getCNgnDecimals(chain: string): number | undefined;
|
|
286
|
-
getExtAsset(chain: string): HexString | undefined;
|
|
287
|
-
getExtDecimals(chain: string): number | undefined;
|
|
288
|
-
getConfiguredChainIds(): number[];
|
|
289
|
-
getLoggingConfig(): LogLevel | undefined;
|
|
290
|
-
getHyperbridgeAddress(): string;
|
|
291
|
-
getHyperbridgeWsUrl(): string | undefined;
|
|
292
|
-
getSubstratePrivateKey(): string | undefined;
|
|
293
|
-
getEntryPointAddress(chain: string): HexString | undefined;
|
|
294
|
-
getSolverAccountContractAddress(chain: string): HexString | undefined;
|
|
295
|
-
getBundlerUrl(chain: string): string | undefined;
|
|
296
|
-
/**
|
|
297
|
-
* Get the maxPriorityFeePerGas bump percentage.
|
|
298
|
-
* @returns The configured percentage or undefined if not set (default 8% will be used)
|
|
299
|
-
*/
|
|
300
|
-
getMaxPriorityFeePerGasBumpPercent(): number | undefined;
|
|
301
|
-
/**
|
|
302
|
-
* Get the maxFeePerGas bump percentage.
|
|
303
|
-
* @returns The configured percentage or undefined if not set (default 10% will be used)
|
|
304
|
-
*/
|
|
305
|
-
getMaxFeePerGasBumpPercent(): number | undefined;
|
|
306
|
-
/**
|
|
307
|
-
* Get the full gas fee bump configuration.
|
|
308
|
-
* @returns The gas fee bump config or undefined if not set
|
|
309
|
-
*/
|
|
310
|
-
getGasFeeBumpConfig(): GasFeeBumpConfig | undefined;
|
|
311
|
-
/**
|
|
312
|
-
* Get the LayerZero Endpoint ID for the chain
|
|
313
|
-
* Used for USDT0 cross-chain transfers via LayerZero OFT
|
|
314
|
-
*/
|
|
315
|
-
getLayerZeroEid(chain: string): number | undefined;
|
|
316
|
-
/**
|
|
317
|
-
* Get the USDT0 OFT contract address for the chain
|
|
318
|
-
* On Ethereum: OFT Adapter (locks/unlocks USDT)
|
|
319
|
-
* On other chains: OFT contract (mints/burns USDT0)
|
|
320
|
-
*/
|
|
321
|
-
getUsdt0OftAddress(chain: string): HexString | undefined;
|
|
322
|
-
/**
|
|
323
|
-
* Get rebalancing configuration
|
|
324
|
-
*/
|
|
325
|
-
getRebalancingConfig(): RebalancingConfig$1 | undefined;
|
|
326
|
-
/**
|
|
327
|
-
* Get base balance for a specific chain and asset
|
|
328
|
-
* @param chainId Chain ID as number
|
|
329
|
-
* @param asset "USDC" or "USDT"
|
|
330
|
-
* @returns Base balance as Decimal, or undefined if not configured
|
|
331
|
-
*/
|
|
332
|
-
getBaseBalance(chainId: number, asset: "USDC" | "USDT"): number | undefined;
|
|
333
|
-
/**
|
|
334
|
-
* Get trigger percentage for rebalancing
|
|
335
|
-
* @returns Trigger percentage (0-1), or undefined if not configured
|
|
336
|
-
*/
|
|
337
|
-
getTriggerPercentage(): number | undefined;
|
|
338
|
-
/**
|
|
339
|
-
* Get target gas units for EntryPoint deposits.
|
|
340
|
-
* Defaults to 3,000,000 if not configured.
|
|
341
|
-
*/
|
|
342
|
-
getTargetGasUnits(): bigint;
|
|
343
|
-
/**
|
|
344
|
-
* How long a signed bid remains executable, in seconds. Defaults to 300 (5 minutes).
|
|
345
|
-
*
|
|
346
|
-
* A bid is a firm price the placer may take up at a moment of their choosing; this is the
|
|
347
|
-
* only thing bounding that window, since the order deadline is placer-controlled and
|
|
348
|
-
* Hyperbridge-side retraction does not reach the destination chain.
|
|
349
|
-
*/
|
|
350
|
-
getBidValiditySeconds(): number;
|
|
351
|
-
/**
|
|
352
|
-
* The order size, in USD, below which `order.fees` must cover the execution cost.
|
|
353
|
-
* Defaults to 20. An order at or above it is filled whatever fees it carries.
|
|
354
|
-
*/
|
|
355
|
-
getMinOrderSizeUsd(): number;
|
|
356
|
-
/** Ceiling bps above user-requested output. Default 500 (5%). */
|
|
357
|
-
getMaxOverfillBps(): bigint;
|
|
358
|
-
/** Consecutive clamped evaluations before the strategy halts. Default 3. */
|
|
359
|
-
getMaxConsecutiveClamps(): number;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* What one quorum call is allowed to spend.
|
|
364
|
-
*
|
|
365
|
-
* `deadlineMs` is the ceiling on the call itself: past it, the endpoints still
|
|
366
|
-
* outstanding are treated as failures, so they stop voting and the call is
|
|
367
|
-
* decided over the endpoints that answered, or fails with a QuorumError naming
|
|
368
|
-
* them. Early exit decides as soon as the endpoints still out could not change
|
|
369
|
-
* the outcome; the deadline decides when one of them never answers.
|
|
370
|
-
*
|
|
371
|
-
* `timeoutMs` bounds one endpoint's attempt, and there is only ever one: the
|
|
372
|
-
* transports are built with `retryCount: 0`, so an endpoint's whole
|
|
373
|
-
* contribution to a call is a single request. That is what keeps the two
|
|
374
|
-
* numbers independent — a task cannot approach `deadlineMs` by retrying inside
|
|
375
|
-
* itself, so a deadline that fires means something outside the budget went
|
|
376
|
-
* wrong rather than an endpoint using the budget as designed.
|
|
377
|
-
*/
|
|
378
|
-
interface QuorumBudget {
|
|
379
|
-
timeoutMs: number;
|
|
380
|
-
deadlineMs: number;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Wraps multiple viem `PublicClient`s — one per configured RPC URL — and runs
|
|
384
|
-
* selected read paths (`getLogs`, `getBlockNumber`, `getTransactionConfirmations`)
|
|
385
|
-
* as a **BFT quorum**: a result is accepted only when `quorumThreshold(m)` of the
|
|
386
|
-
* `m` endpoints that answered agree on it.
|
|
387
|
-
*
|
|
388
|
-
* A provider that *answers with divergent data* is never special-cased away — it
|
|
389
|
-
* simply fails to join the agreeing group, which is what makes a lying or reorged
|
|
390
|
-
* endpoint detectable rather than authoritative.
|
|
391
|
-
*
|
|
392
|
-
* A provider that *fails* does not vote. A failed request says nothing about the
|
|
393
|
-
* chain, so it must not outvote the endpoints that agree: the threshold guards
|
|
394
|
-
* against endpoints that answer wrongly, and every answer still counts. Six
|
|
395
|
-
* endpoints with two failing decide over the other four, three of which must
|
|
396
|
-
* agree. The price, worth stating plainly, is that a call can be decided by fewer
|
|
397
|
-
* endpoints than the operator configured; at the limit, one endpoint answering
|
|
398
|
-
* while the rest fail decides alone. The voters are still exclusively the
|
|
399
|
-
* operator's own.
|
|
400
|
-
*
|
|
401
|
-
* The bench is the one state this class keeps, and {@link benchFor} decides who
|
|
402
|
-
* goes on it: a request-rate limit ({@link isSuspendableRateLimit}), a response
|
|
403
|
-
* that is not JSON ({@link isMalformedResponse}), or a head behind the quorum's
|
|
404
|
-
* ({@link isStaleHead}). All three share the property that earns it — the
|
|
405
|
-
* endpoint will keep failing the same way for a while — so a benched endpoint is
|
|
406
|
-
* not asked for its window: asking would spend its quota, or hold the call open
|
|
407
|
-
* for an answer already known to fail. When every endpoint is benched, all are
|
|
408
|
-
* queried again; there is nobody left to prefer. Every other failure is per
|
|
409
|
-
* call, and the endpoint is asked again next time.
|
|
410
|
-
*
|
|
411
|
-
* The constructor validates that URLs resolve to distinct hostnames so a "quorum"
|
|
412
|
-
* isn't secretly the same upstream in disguise.
|
|
413
|
-
*/
|
|
414
|
-
declare class QuorumPublicClient {
|
|
415
|
-
readonly clients: PublicClient[];
|
|
416
|
-
readonly rpcUrls: string[];
|
|
417
|
-
/**
|
|
418
|
-
* The quorum bar when every endpoint answers: `quorumThreshold(n)` over the
|
|
419
|
-
* full set. Each call's bar is `quorumThreshold` over the endpoints that answer
|
|
420
|
-
* it, so this is the most it can be.
|
|
421
|
-
*/
|
|
422
|
-
readonly threshold: number;
|
|
423
|
-
private readonly logger?;
|
|
424
|
-
/**
|
|
425
|
-
* Rate-limit bench state, shared across every instance and keyed by endpoint
|
|
426
|
-
* URL. The bench describes the ENDPOINT, not the wrapper: the scanner and the
|
|
427
|
-
* confirmation poller construct separate clients over the same URLs, and a
|
|
428
|
-
* throttle one of them observed is a throttle for both. Instance state would
|
|
429
|
-
* halve the relief — and evaporate whenever `setRpcUrls` rebuilds a client.
|
|
430
|
-
*/
|
|
431
|
-
private static benchedUntil;
|
|
432
|
-
/** Test hook: forgets every bench. Production never calls it. */
|
|
433
|
-
static clearAllSuspensions(): void;
|
|
434
|
-
/** What this client's calls may spend; see {@link QuorumBudget}. */
|
|
435
|
-
private readonly deadlineMs;
|
|
436
|
-
constructor(chainId: number, rpcUrls: string[], loggers?: LoggerContext, budget?: QuorumBudget);
|
|
437
|
-
get size(): number;
|
|
438
|
-
/** Endpoints currently benched, by URL. See {@link benchFor} for the reasons. */
|
|
439
|
-
suspended(): string[];
|
|
440
|
-
/**
|
|
441
|
-
* The endpoints this call queries: everyone not benched. A benched endpoint is
|
|
442
|
-
* dropped outright: it answers nothing while throttled, so asking it could only
|
|
443
|
-
* cost a request. With every endpoint benched, everyone is queried again; there
|
|
444
|
-
* is nobody left to prefer.
|
|
445
|
-
*/
|
|
446
|
-
private participants;
|
|
447
|
-
/**
|
|
448
|
-
* Records a task failure against its endpoint. Only the failures
|
|
449
|
-
* {@link benchFor} names carry state: everything else stays per-call, as the
|
|
450
|
-
* class doc promises.
|
|
451
|
-
* The bench is the one silent state transition this class has, so it warns —
|
|
452
|
-
* an operator whose bar just dropped from 2-of-2 to 1-of-1 should not need a
|
|
453
|
-
* QuorumError to find out.
|
|
454
|
-
*/
|
|
455
|
-
private noteFailure;
|
|
456
|
-
/**
|
|
457
|
-
* Highest block a quorum of endpoints have all indexed: the highest B such
|
|
458
|
-
* that `threshold` endpoints report head ≥ B. Returns null when fewer than
|
|
459
|
-
* `threshold` endpoints have responded.
|
|
460
|
-
*/
|
|
461
|
-
private quorumHead;
|
|
462
|
-
/**
|
|
463
|
-
* Settles per-client tasks incrementally and resolves the moment the
|
|
464
|
-
* evaluator can decide from the responses seen so far — the hot path never
|
|
465
|
-
* blocks on the slowest provider (a hung endpoint with a 30s timeout × 3
|
|
466
|
-
* retries would otherwise stall every confirmation poll). Stragglers settle
|
|
467
|
-
* out of band and are ignored. `tryDecide` returns undefined to keep
|
|
468
|
-
* waiting; once every task has settled, `finalize` must decide (it throws
|
|
469
|
-
* the QuorumError when the full response set still has no quorum).
|
|
470
|
-
*
|
|
471
|
-
* Both are handed the bar: the BFT threshold over the endpoints that have not
|
|
472
|
-
* failed, answered or still out. A failure lowers it rather than counting
|
|
473
|
-
* against it. Counting the pending endpoints keeps an early decision to a bar
|
|
474
|
-
* no lower than the full response set would get, so a vote it did not wait for
|
|
475
|
-
* could never have reversed it.
|
|
476
|
-
*
|
|
477
|
-
* `deadlineMs` bounds the other direction: when the bar is NOT reachable
|
|
478
|
-
* from the fast responders, the call used to wait out every straggler, and
|
|
479
|
-
* the caller's own retry loop multiplied that into minutes of a chain not
|
|
480
|
-
* being scanned at all, silently. At the deadline the outstanding endpoints
|
|
481
|
-
* are treated as failures — named in the QuorumError, so the operator sees
|
|
482
|
-
* which ones held the call up — and `finalize` decides over the endpoints
|
|
483
|
-
* that answered.
|
|
484
|
-
*/
|
|
485
|
-
private settleUntilQuorum;
|
|
486
|
-
/**
|
|
487
|
-
* Highest block head backed by a quorum of the endpoints that answer. Throws
|
|
488
|
-
* {@link QuorumError} when none do.
|
|
489
|
-
*/
|
|
490
|
-
getBlockNumber(): Promise<bigint>;
|
|
491
|
-
/**
|
|
492
|
-
* Confirmation count for a transaction under the quorum.
|
|
493
|
-
*
|
|
494
|
-
* Every endpoint is asked for the receipt and its head. A "receipt not found"
|
|
495
|
-
* answer is a valid **no** vote — the endpoint is responsive but does not see
|
|
496
|
-
* the transaction (not yet propagated, or reorged out) — so it counts toward
|
|
497
|
-
* responsiveness but joins no inclusion group. The transaction is confirmed
|
|
498
|
-
* only when a quorum agrees on the same `(blockHash, blockNumber)`; the depth
|
|
499
|
-
* is then the quorum head of that agreeing group. A minority still serving a
|
|
500
|
-
* reorged/fabricated receipt can never reach the quorum.
|
|
501
|
-
*
|
|
502
|
-
* Throws {@link QuorumError} when no inclusion reaches the quorum — including
|
|
503
|
-
* the ordinary window where the tx is not yet mined on enough endpoints.
|
|
504
|
-
*/
|
|
505
|
-
getTransactionConfirmations({ hash }: {
|
|
506
|
-
hash: Hash;
|
|
507
|
-
}): Promise<bigint>;
|
|
508
|
-
/**
|
|
509
|
-
* Fetches logs from every endpoint in parallel and returns the result once a
|
|
510
|
-
* quorum agrees. Fails with {@link QuorumError} otherwise.
|
|
511
|
-
*
|
|
512
|
-
* Generics mirror `PublicClient.getLogs` so caller-side inference (event decoding,
|
|
513
|
-
* strict mode, pending vs mined) is preserved end-to-end.
|
|
514
|
-
*/
|
|
515
|
-
getLogs<const TAbiEvent extends AbiEvent | undefined = undefined, const TAbiEvents extends readonly AbiEvent[] | readonly unknown[] | undefined = TAbiEvent extends AbiEvent ? [TAbiEvent] : undefined, TStrict extends boolean | undefined = undefined, TFromBlock extends BlockNumber | BlockTag | undefined = undefined, TToBlock extends BlockNumber | BlockTag | undefined = undefined>(params: GetLogsParameters<TAbiEvent, TAbiEvents, TStrict, TFromBlock, TToBlock>): Promise<GetLogsReturnType<TAbiEvent, TAbiEvents, TStrict, TFromBlock, TToBlock>>;
|
|
516
|
-
/**
|
|
517
|
-
* `skipped` is the participants() snapshot for THIS call, not the suspension
|
|
518
|
-
* state at throw time — a call that rides out its deadline can outlive a
|
|
519
|
-
* bench window, and the message must explain
|
|
520
|
-
* who was excluded when the call started, not who would be excluded now.
|
|
521
|
-
*/
|
|
522
|
-
private describeResponders;
|
|
523
|
-
private formatFailures;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* The signing contract a solver runs on, and the config shapes the bundled
|
|
528
|
-
* implementations take.
|
|
529
|
-
*
|
|
530
|
-
* `Signer` is the whole surface: implement it and Simplex signs with your
|
|
531
|
-
* backend. Nothing here is viem-shaped, so a consumer never has to match this
|
|
532
|
-
* package's viem version to satisfy it — `viemSigner` adapts a viem account into
|
|
533
|
-
* one, and simplex builds the account its wallet clients need from whatever it
|
|
534
|
-
* is given.
|
|
535
|
-
*/
|
|
536
|
-
|
|
537
|
-
interface MpcVaultSignerConfig {
|
|
538
|
-
apiToken: string;
|
|
539
|
-
vaultUuid: string;
|
|
540
|
-
accountAddress: HexString;
|
|
541
|
-
callbackClientSignerPublicKey: string;
|
|
542
|
-
/**
|
|
543
|
-
* gRPC target address. Defaults to "api.mpcvault.com:443".
|
|
544
|
-
* Replaces the previous REST `baseUrl` field.
|
|
545
|
-
*/
|
|
546
|
-
grpcTarget?: string;
|
|
547
|
-
/**
|
|
548
|
-
* Destination for signing lifecycle logs. Defaults to the process-wide
|
|
549
|
-
* context, which an embedded filler's `SimplexOptions.logger` never sees —
|
|
550
|
-
* pass your own to capture retries and failures in that setup.
|
|
551
|
-
*/
|
|
552
|
-
logger?: Logger;
|
|
553
|
-
/** Channel credentials override for tests against a plaintext server. Defaults to TLS. */
|
|
554
|
-
credentials?: ChannelCredentials;
|
|
555
|
-
}
|
|
556
|
-
declare enum SignerType {
|
|
557
|
-
PrivateKey = "privateKey",
|
|
558
|
-
MpcVault = "mpcVault",
|
|
559
|
-
Turnkey = "turnkey",
|
|
560
|
-
SecretPhrase = "secretPhrase"
|
|
561
|
-
}
|
|
562
|
-
interface TurnkeySignerConfig {
|
|
563
|
-
organizationId: string;
|
|
564
|
-
apiPublicKey: string;
|
|
565
|
-
apiPrivateKey: string;
|
|
566
|
-
signWith: string;
|
|
567
|
-
}
|
|
568
|
-
interface PrivateKeySignerConfig {
|
|
569
|
-
key: HexString;
|
|
570
|
-
}
|
|
571
|
-
interface SecretPhraseSignerConfig {
|
|
572
|
-
/** BIP-39 mnemonic from the English wordlist. */
|
|
573
|
-
phrase: string;
|
|
574
|
-
/**
|
|
575
|
-
* Which wallet under the phrase is the hot wallet: the last component of
|
|
576
|
-
* `m/44'/60'/0'/0/i`. Defaults to 0.
|
|
577
|
-
*/
|
|
578
|
-
accountIndex?: number;
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* The `[simplex.signer]` block of the TOML file the binary reads — a tagged
|
|
582
|
-
* union over the bundled backends. `createSigner` turns one into a {@link Signer};
|
|
583
|
-
* `Simplex.start` takes the `Signer`, not this.
|
|
584
|
-
*/
|
|
585
|
-
type SignerConfig = ({
|
|
586
|
-
type: SignerType.PrivateKey;
|
|
587
|
-
} & PrivateKeySignerConfig) | ({
|
|
588
|
-
type: SignerType.MpcVault;
|
|
589
|
-
} & MpcVaultSignerConfig) | ({
|
|
590
|
-
type: SignerType.Turnkey;
|
|
591
|
-
} & TurnkeySignerConfig) | ({
|
|
592
|
-
type: SignerType.SecretPhrase;
|
|
593
|
-
} & SecretPhraseSignerConfig);
|
|
594
|
-
/**
|
|
595
|
-
* A secp256k1 signature in split form, which is how EIP-7702 and raw digests
|
|
596
|
-
* consume it: `r` and `s` as 32-byte 0x-hex, and `yParity` strictly 0 or 1.
|
|
597
|
-
* A backend that hands back the legacy `v` (27/28) should subtract 27 — the
|
|
598
|
-
* delegation path rejects anything else rather than letting viem mis-encode it.
|
|
599
|
-
*/
|
|
600
|
-
interface Signature {
|
|
601
|
-
r: HexString;
|
|
602
|
-
s: HexString;
|
|
603
|
-
yParity: number;
|
|
604
|
-
}
|
|
605
|
-
/**
|
|
606
|
-
* An EIP-712 payload, as `eth_signTypedData_v4` defines it.
|
|
607
|
-
*
|
|
608
|
-
* `domain.chainId` is the only field a signing backend is likely to read for
|
|
609
|
-
* itself: the digest covers it, and backends that scope a signing request to a
|
|
610
|
-
* chain (MPCVault) take it from here rather than from a separate argument.
|
|
611
|
-
*
|
|
612
|
-
* **List `EIP712Domain` in `types` on any payload you build.** viem ignores it
|
|
613
|
-
* when hashing locally, so a payload without it looks correct against a private
|
|
614
|
-
* key. Backends that hash server-side from the JSON derive the domain type from
|
|
615
|
-
* that entry — MPCVault and Turnkey both do — and without it they sign a
|
|
616
|
-
* different digest than the one your verifier checks. The failure is quiet: the
|
|
617
|
-
* signature is well-formed and recovers to an address that is not yours.
|
|
618
|
-
* `CryptoUtils.packedUserOpTypedData` in the sdk sets it for this reason.
|
|
619
|
-
*/
|
|
620
|
-
interface TypedDataPayload {
|
|
621
|
-
domain?: {
|
|
622
|
-
name?: string;
|
|
623
|
-
version?: string;
|
|
624
|
-
chainId?: number | bigint;
|
|
625
|
-
verifyingContract?: HexString;
|
|
626
|
-
salt?: HexString;
|
|
627
|
-
};
|
|
628
|
-
types: Record<string, readonly {
|
|
629
|
-
name: string;
|
|
630
|
-
type: string;
|
|
631
|
-
}[]>;
|
|
632
|
-
primaryType: string;
|
|
633
|
-
message: Record<string, unknown>;
|
|
634
|
-
}
|
|
635
|
-
/** EIP-7702 authorization tuple, signed, as a set-code transaction carries it. */
|
|
636
|
-
interface Eip7702Authorization$1 extends Signature {
|
|
637
|
-
chainId: number;
|
|
638
|
-
address: HexString;
|
|
639
|
-
nonce: number;
|
|
640
|
-
}
|
|
641
|
-
/**
|
|
642
|
-
* A transaction to sign, handed to backends that implement
|
|
643
|
-
* {@link Signer.signTransaction}. Field names follow the JSON-RPC transaction
|
|
644
|
-
* object; simplex only ever sends EIP-1559 transfers and EIP-7702 set-code
|
|
645
|
-
* transactions, so those are the fields modelled here.
|
|
646
|
-
*/
|
|
647
|
-
interface SignerTransaction {
|
|
648
|
-
chainId: number;
|
|
649
|
-
type?: string;
|
|
650
|
-
to?: HexString;
|
|
651
|
-
value?: bigint;
|
|
652
|
-
data?: HexString;
|
|
653
|
-
nonce?: number;
|
|
654
|
-
gas?: bigint;
|
|
655
|
-
maxFeePerGas?: bigint;
|
|
656
|
-
maxPriorityFeePerGas?: bigint;
|
|
657
|
-
/** Present on EIP-7702 set-code transactions, and on nothing else. */
|
|
658
|
-
authorizationList?: Eip7702Authorization$1[];
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Everything a solver asks of the key that owns its funds. Pass an
|
|
662
|
-
* implementation to `Simplex.start({ signer })`.
|
|
663
|
-
*
|
|
664
|
-
* Three operations, one identity. Each operation names what is being authorised
|
|
665
|
-
* — a typed-data payload, an EIP-7702 authorization, a transaction — rather than
|
|
666
|
-
* a digest, so a custody backend's policy engine can read what it is signing.
|
|
667
|
-
*
|
|
668
|
-
* A backend that only signs digests does not implement this by hand: pass its
|
|
669
|
-
* `sign(hash)` to {@link digestSigner}, which does the hashing and serialising
|
|
670
|
-
* and returns a `Signer`.
|
|
671
|
-
*/
|
|
672
|
-
interface Signer {
|
|
673
|
-
/** The address every fill, bid and delegation is attributed to. */
|
|
674
|
-
readonly address: HexString;
|
|
675
|
-
/** Names the backend in logs — `"privateKey"`, `"turnkey"`, or whatever names yours. */
|
|
676
|
-
readonly mode: string;
|
|
677
|
-
/**
|
|
678
|
-
* EIP-712. Signs every bid UserOperation and every paymaster permit.
|
|
679
|
-
*
|
|
680
|
-
* Returns the 65-byte `r ‖ s ‖ v` signature as 0x-hex (132 characters), with
|
|
681
|
-
* `v` 27 or 28 — exactly what `eth_signTypedData_v4` and viem's
|
|
682
|
-
* `signTypedData` produce. On-chain validation recovers against this form.
|
|
683
|
-
*/
|
|
684
|
-
signTypedData(typedData: TypedDataPayload): Promise<HexString>;
|
|
685
|
-
/**
|
|
686
|
-
* Signs an EIP-7702 authorization tuple — the delegation that makes this
|
|
687
|
-
* account a solver. Backends with a structured encoding for it (Turnkey) use
|
|
688
|
-
* that; others sign `keccak256(0x05 ‖ rlp([chainId, contractAddress, nonce]))`.
|
|
689
|
-
*
|
|
690
|
-
* Returns the SPLIT signature — see {@link Signature}: `yParity` must be 0 or
|
|
691
|
-
* 1, not the legacy `v`. This is the one method that does not return hex,
|
|
692
|
-
* because the authorization is embedded field-by-field in the transaction.
|
|
693
|
-
*/
|
|
694
|
-
signAuthorization(auth: AuthorizationRequest): Promise<Signature>;
|
|
695
|
-
/**
|
|
696
|
-
* Signs and serialises a transaction. Backends that take transactions
|
|
697
|
-
* (MPCVault's vault API, Turnkey's transaction payloads) keep the transaction
|
|
698
|
-
* legible to their policy engine; others serialise it and sign the digest.
|
|
699
|
-
*
|
|
700
|
-
* Returns the WHOLE SIGNED TRANSACTION — typed-envelope RLP as
|
|
701
|
-
* `eth_sendRawTransaction` takes it (`0x02…` for EIP-1559, `0x04…` for
|
|
702
|
-
* set-code), not a bare signature. viem's `serializeTransaction(tx, signature)`
|
|
703
|
-
* produces it from a signed digest.
|
|
704
|
-
*/
|
|
705
|
-
signTransaction(tx: SignerTransaction): Promise<HexString>;
|
|
706
|
-
}
|
|
707
|
-
/**
|
|
708
|
-
* A {@link Signer} backed by a key tree rather than a single key, so it can hand
|
|
709
|
-
* out signers for sibling wallets.
|
|
710
|
-
*/
|
|
711
|
-
interface DerivingSigner extends Signer {
|
|
712
|
-
/** Index of the wallet this signer itself signs with. */
|
|
713
|
-
readonly accountIndex: number;
|
|
714
|
-
/** The signer for the wallet at `index`, which may be this signer's own. */
|
|
715
|
-
derive(index: number): Signer;
|
|
716
|
-
}
|
|
717
|
-
/** The tuple an EIP-7702 authorization signature covers. */
|
|
718
|
-
interface AuthorizationRequest {
|
|
719
|
-
chainId: number;
|
|
720
|
-
/** The contract the account delegates to. */
|
|
721
|
-
contractAddress: HexString;
|
|
722
|
-
nonce: number;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
105
|
/**
|
|
726
106
|
* Builds the signer a `[simplex.signer]` TOML block describes.
|
|
727
107
|
*
|
|
@@ -813,140 +193,223 @@ declare function mpcVaultSigner(config: MpcVaultSignerConfig): Signer;
|
|
|
813
193
|
*/
|
|
814
194
|
declare function turnkeySigner(config: TurnkeySignerConfig): Promise<Signer>;
|
|
815
195
|
|
|
816
|
-
/**
|
|
817
|
-
|
|
818
|
-
*/
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
* The viem account every wallet client is built on, derived from the signer
|
|
823
|
-
* once. `Signer` is viem-free by design, so this is where the two meet.
|
|
824
|
-
*/
|
|
825
|
-
private account;
|
|
826
|
-
private configService;
|
|
827
|
-
private clientFactory;
|
|
828
|
-
private quorumClients;
|
|
829
|
-
/** This filler's logging destination, relayed from the config service. */
|
|
830
|
-
get loggers(): LoggerContext;
|
|
831
|
-
constructor(configService: FillerConfigService, signer?: Signer);
|
|
832
|
-
/**
|
|
833
|
-
* Drops every cached client for a chain. Call after the chain's RPC URLs
|
|
834
|
-
* change (or when the chain is removed) so the next lookup rebuilds against
|
|
835
|
-
* the current endpoints — transports are baked into a client at construction.
|
|
836
|
-
*
|
|
837
|
-
* Callers that hold a client reference across the invalidation keep talking to
|
|
838
|
-
* the old endpoints; `EventMonitor` re-reads its quorum client per chain
|
|
839
|
-
* rebuild for exactly this reason.
|
|
840
|
-
*/
|
|
841
|
-
invalidate(chain: string): void;
|
|
842
|
-
getPublicClient(chain: string): PublicClient;
|
|
843
|
-
/**
|
|
844
|
-
* Quorum client for consensus-critical reads (cross-chain confirmation
|
|
845
|
-
* counting; the scanner builds its own instance over its own chain list).
|
|
846
|
-
* Built from the operator's configured endpoints and cached per chain. The
|
|
847
|
-
* instances are separate but their rate-limit bench is shared state keyed by
|
|
848
|
-
* endpoint URL, so a throttle either observes benches the endpoint for both.
|
|
849
|
-
*/
|
|
850
|
-
getQuorumClient(chain: string): QuorumPublicClient;
|
|
851
|
-
getWalletClient(chain: string): WalletClient<Transport, Chain, Account>;
|
|
852
|
-
getAccount(): Account;
|
|
853
|
-
getSigner(): Signer;
|
|
854
|
-
getClientsForOrder(order: Order): {
|
|
855
|
-
destClient: PublicClient;
|
|
856
|
-
sourceClient: PublicClient;
|
|
857
|
-
walletClient: WalletClient<Transport, Chain, Account>;
|
|
858
|
-
};
|
|
196
|
+
/** Native gas a chain needs before its paymaster can sponsor the wallet's transactions. */
|
|
197
|
+
interface NativeSetupNeed {
|
|
198
|
+
/** Native to send, in whole units: twice the current cost, so a gas-price rise does not leave it short. */
|
|
199
|
+
required: number;
|
|
200
|
+
/** The fee token whose one-time Permit2 approval has to be paid in native. */
|
|
201
|
+
feeToken: "USDC" | "USDT";
|
|
859
202
|
}
|
|
860
203
|
|
|
861
|
-
|
|
862
|
-
* Raw EIP-7702 authorization, as produced by the delegation flow. Attached to the
|
|
863
|
-
* bundler UserOp so a not-yet-delegated EOA can be delegated in the same op.
|
|
864
|
-
*/
|
|
865
|
-
interface Eip7702Authorization {
|
|
204
|
+
interface ChainBalanceRow {
|
|
866
205
|
chainId: number;
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
206
|
+
native?: {
|
|
207
|
+
symbol: string;
|
|
208
|
+
amount: number;
|
|
209
|
+
};
|
|
210
|
+
usdc?: number;
|
|
211
|
+
usdt?: number;
|
|
212
|
+
exotics?: Array<{
|
|
213
|
+
symbol: string;
|
|
214
|
+
amount: number;
|
|
215
|
+
}>;
|
|
216
|
+
/** Canonical token balances, including funds held in configured ERC-4626 vaults. */
|
|
217
|
+
assets: AssetBalanceRow[];
|
|
218
|
+
/** Set when the paymaster cannot sponsor this chain until the wallet holds some native gas. */
|
|
219
|
+
nativeSetup?: NativeSetupNeed;
|
|
872
220
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
221
|
+
type AssetBalanceStatus = "fresh" | "partial" | "unavailable";
|
|
222
|
+
interface VaultBalanceRow {
|
|
223
|
+
address: string;
|
|
224
|
+
position: number;
|
|
225
|
+
available: number;
|
|
226
|
+
/** False while the vault reports `maxDeposit(solver) == 0`; sweeps into it are idle until it reopens. */
|
|
227
|
+
acceptsDeposits: boolean;
|
|
877
228
|
}
|
|
878
|
-
interface
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
229
|
+
interface AssetBalanceRow {
|
|
230
|
+
address: string;
|
|
231
|
+
symbol: string;
|
|
232
|
+
/** Direct underlying balance held by the solver account. Null when its RPC read failed. */
|
|
233
|
+
wallet: number | null;
|
|
234
|
+
/** Configured wallet floor that must remain liquid. */
|
|
235
|
+
walletReserve: number;
|
|
236
|
+
/** Total solver-owned underlying represented by vault shares. */
|
|
237
|
+
vaultPosition: number;
|
|
238
|
+
/** Vault assets that can be withdrawn now, after pending-fill reservations. */
|
|
239
|
+
vaultAvailable: number;
|
|
240
|
+
/** Wallet plus vault position. Null when any required source was unavailable. */
|
|
241
|
+
total: number | null;
|
|
242
|
+
/** Spendable wallet above reserve plus currently withdrawable vault assets. */
|
|
243
|
+
available: number | null;
|
|
244
|
+
vaults: VaultBalanceRow[];
|
|
245
|
+
status: AssetBalanceStatus;
|
|
246
|
+
}
|
|
247
|
+
type BalanceIssueSource = "chain" | "native" | "token" | "vault";
|
|
248
|
+
interface BalanceIssue {
|
|
249
|
+
chainId?: number;
|
|
250
|
+
source: BalanceIssueSource;
|
|
251
|
+
asset?: string;
|
|
252
|
+
message: string;
|
|
253
|
+
}
|
|
254
|
+
type BalanceSnapshotStatus = "loading" | "fresh" | "partial" | "unavailable";
|
|
255
|
+
interface HyperbridgeBalance {
|
|
256
|
+
address: string;
|
|
257
|
+
free: number;
|
|
258
|
+
reserved: number;
|
|
259
|
+
}
|
|
260
|
+
interface BalanceSnapshot {
|
|
261
|
+
/** null until the first refresh attempt completes. */
|
|
262
|
+
updatedAt: number | null;
|
|
263
|
+
status: BalanceSnapshotStatus;
|
|
264
|
+
chains: ChainBalanceRow[];
|
|
265
|
+
issues: BalanceIssue[];
|
|
266
|
+
hyperbridge?: HyperbridgeBalance;
|
|
267
|
+
}
|
|
268
|
+
/** Narrow read-only seam implemented by the vault funding planner. */
|
|
269
|
+
interface VaultBalanceSource {
|
|
270
|
+
getBalanceSnapshot(chain?: string): Promise<VaultBalancePosition[]>;
|
|
271
|
+
}
|
|
272
|
+
interface BalanceProviderOptions {
|
|
273
|
+
chainClientManager: ChainClientManager;
|
|
274
|
+
configService: FillerConfigService;
|
|
275
|
+
fillerAddress: string;
|
|
892
276
|
/**
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
277
|
+
* Token addresses to read beyond USDC and USDT, by state machine id: every token of the
|
|
278
|
+
* orderbook's books. Asked on each refresh, so a book the orderbook adds is picked up
|
|
279
|
+
* without a restart.
|
|
896
280
|
*/
|
|
897
|
-
|
|
281
|
+
tokens: () => Promise<Record<string, string[]>>;
|
|
898
282
|
/**
|
|
899
|
-
*
|
|
900
|
-
*
|
|
901
|
-
*
|
|
902
|
-
* makes every later Permit2 op possible without native.
|
|
283
|
+
* The filler's Hyperbridge connection, reused rather than dialled again. A second socket to the
|
|
284
|
+
* same node doubles the reconnect traffic during an outage for a balance read that is only
|
|
285
|
+
* needed once a minute.
|
|
903
286
|
*/
|
|
904
|
-
|
|
287
|
+
hyperbridge?: Promise<IntentsCoprocessor>;
|
|
288
|
+
substratePrivateKey?: string;
|
|
289
|
+
refreshIntervalMs?: number;
|
|
290
|
+
vaultBalances?: VaultBalanceSource;
|
|
905
291
|
}
|
|
906
292
|
/**
|
|
907
|
-
*
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
* Submission contract (so callers can safely fall back to a native tx without
|
|
912
|
-
* risking a double-execution):
|
|
913
|
-
* - Returns `null` when the op was **never submitted** — paymaster/bundler not
|
|
914
|
-
* configured, insufficient USDC, preparation failed (approve tx or signing), or
|
|
915
|
-
* the bundler rejected `eth_sendUserOperation` outright (it never entered the
|
|
916
|
-
* mempool). The caller may fall back to native.
|
|
917
|
-
* - Returns `{ txHash }` once a receipt is observed.
|
|
918
|
-
* - **Throws** only when the op **was submitted** but no receipt arrived. The
|
|
919
|
-
* caller must NOT fall back (the op may still land) — retry on the next cycle.
|
|
293
|
+
* Periodically collects wallet balances (native, USDC, USDT and the other tokens
|
|
294
|
+
* of the orderbook's books per chain, plus the BRIDGE balance of the substrate
|
|
295
|
+
* account) into a plain snapshot,
|
|
296
|
+
* consumed by the UI JSON API and `wallet.balances()`.
|
|
920
297
|
*/
|
|
921
|
-
declare class
|
|
922
|
-
private
|
|
923
|
-
private
|
|
924
|
-
private
|
|
298
|
+
declare class BalanceProvider extends EventEmitter {
|
|
299
|
+
private snapshot;
|
|
300
|
+
private stopped;
|
|
301
|
+
private refreshInterval?;
|
|
302
|
+
private hyperbridgeInterval?;
|
|
925
303
|
private logger;
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
*/
|
|
937
|
-
private estimateGas;
|
|
938
|
-
private buildSignedUserOp;
|
|
939
|
-
/**
|
|
940
|
-
* Mirrors the gas-price selection used by the delegation and fill paths: Pimlico's and
|
|
941
|
-
* Alchemy's own pricing, otherwise the chain's gas price raised to the priority fee a
|
|
942
|
-
* rundler bundler requires, when the bundler gives one.
|
|
943
|
-
*/
|
|
944
|
-
private getGasPrice;
|
|
945
|
-
private sendBundlerRpc;
|
|
946
|
-
private waitForUserOpReceipt;
|
|
304
|
+
private options;
|
|
305
|
+
private intervalMs;
|
|
306
|
+
constructor(options: BalanceProviderOptions);
|
|
307
|
+
start(): Promise<void>;
|
|
308
|
+
stop(): void;
|
|
309
|
+
getSnapshot(): BalanceSnapshot;
|
|
310
|
+
refresh(): Promise<BalanceSnapshot>;
|
|
311
|
+
private collectChain;
|
|
312
|
+
private addConfiguredStable;
|
|
313
|
+
private trackHyperbridgeBalance;
|
|
947
314
|
}
|
|
948
315
|
|
|
949
|
-
/**
|
|
316
|
+
/** The stretch of time a summary covers. Each is cut into buckets of one size. */
|
|
317
|
+
type ProfitPeriod = "7d" | "30d" | "12w" | "12m" | "all";
|
|
318
|
+
type ProfitBucket = "day" | "week" | "month" | "year";
|
|
319
|
+
/** What a stretch of fills came to, in dollars at the latest rate. Unpriced tokens are left out. */
|
|
320
|
+
interface ProfitFigures {
|
|
321
|
+
/** What the stretch's fills added to inventory, less what they took out of it. */
|
|
322
|
+
profitUsd: number;
|
|
323
|
+
/** The inventory held when the stretch began. Null when nothing within reach of then records it. */
|
|
324
|
+
startInventoryUsd: number | null;
|
|
325
|
+
/** `profitUsd` over `startInventoryUsd`, as a percentage. Null without a starting inventory. */
|
|
326
|
+
returnPct: number | null;
|
|
327
|
+
/**
|
|
328
|
+
* What moved in and out over the stretch other than through fills, net: deposits, withdrawals,
|
|
329
|
+
* fees and vault yield. Null when the indexer has no reading for both ends of the stretch.
|
|
330
|
+
*/
|
|
331
|
+
transfersUsd: number | null;
|
|
332
|
+
boughtUsd: number;
|
|
333
|
+
soldUsd: number;
|
|
334
|
+
buys: number;
|
|
335
|
+
sells: number;
|
|
336
|
+
}
|
|
337
|
+
interface ProfitBucketFigures extends ProfitFigures {
|
|
338
|
+
/** When the bucket starts, in milliseconds since the epoch. */
|
|
339
|
+
start: number;
|
|
340
|
+
}
|
|
341
|
+
/** One book's buys against its sells over the period, in the book's own tokens. */
|
|
342
|
+
interface BookProfit {
|
|
343
|
+
book: string;
|
|
344
|
+
base: string;
|
|
345
|
+
quote: string;
|
|
346
|
+
/** Base bought and sold in the period. */
|
|
347
|
+
bought: number;
|
|
348
|
+
sold: number;
|
|
349
|
+
/** Quote per base, averaged over the period's buys and its sells. Null for a side with none. */
|
|
350
|
+
averageBuy: number | null;
|
|
351
|
+
averageSell: number | null;
|
|
352
|
+
/** How far the average sell sits above the average buy, as a percentage. Null without both. */
|
|
353
|
+
spreadPct: number | null;
|
|
354
|
+
/** What the period's fills did to the base and the quote held: positive is more than before. */
|
|
355
|
+
baseChange: number;
|
|
356
|
+
quoteChange: number;
|
|
357
|
+
/** The rate the book's tokens are valued at: midway between its latest buy and latest sell. */
|
|
358
|
+
rate: number | null;
|
|
359
|
+
/** Both changes in dollars. Null when the book's tokens have no dollar price. */
|
|
360
|
+
profitUsd: number | null;
|
|
361
|
+
}
|
|
362
|
+
/** The inventory a period began with, token by token. */
|
|
363
|
+
interface StartingInventory {
|
|
364
|
+
/** The instant it describes, in milliseconds since the epoch. */
|
|
365
|
+
at: number;
|
|
366
|
+
/** A stored snapshot, or the balances as they stand now. Either is adjusted by what happened between. */
|
|
367
|
+
source: "snapshot" | "balances";
|
|
368
|
+
/** When that record was taken. */
|
|
369
|
+
recordedAt: number;
|
|
370
|
+
usd: number;
|
|
371
|
+
tokens: Array<{
|
|
372
|
+
symbol: string;
|
|
373
|
+
amount: number;
|
|
374
|
+
usd: number | null;
|
|
375
|
+
}>;
|
|
376
|
+
}
|
|
377
|
+
interface Profitability {
|
|
378
|
+
period: ProfitPeriod;
|
|
379
|
+
bucket: ProfitBucket;
|
|
380
|
+
/** The start of the first bucket and the moment the summary was taken, in milliseconds. */
|
|
381
|
+
from: number;
|
|
382
|
+
to: number;
|
|
383
|
+
totals: ProfitFigures;
|
|
384
|
+
/** One entry per bucket, oldest first, including buckets nothing happened in. */
|
|
385
|
+
series: ProfitBucketFigures[];
|
|
386
|
+
books: BookProfit[];
|
|
387
|
+
/** Null when there is no snapshot, and the period began more than {@link BALANCES_REACH_MS} ago. */
|
|
388
|
+
startInventory: StartingInventory | null;
|
|
389
|
+
/** Fills in the period priced at their order's rate, because they kept no record of what they took in. */
|
|
390
|
+
estimatedFills: number;
|
|
391
|
+
/** Tokens the period touched that have no dollar price, and so are in none of the dollar figures. */
|
|
392
|
+
unpricedTokens: string[];
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Wire contracts between the UI server and the browser bundle. The server
|
|
397
|
+
* types its response literals with these and `ui/src` imports them type-only,
|
|
398
|
+
* so drift on either side is a compile error. Browser-safe: no runtime
|
|
399
|
+
* dependencies beyond constants.
|
|
400
|
+
*/
|
|
401
|
+
|
|
402
|
+
/** Signer work that must finish before the desktop may replace the bundled solver. */
|
|
403
|
+
interface SolverWork {
|
|
404
|
+
queuedEvaluations: number;
|
|
405
|
+
evaluating: number;
|
|
406
|
+
queuedFills: number;
|
|
407
|
+
activeFills: number;
|
|
408
|
+
retractions: number;
|
|
409
|
+
rebalancing: number;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/** One vault's share of a transaction, with the metadata the ledger row needs. */
|
|
950
413
|
interface DescribedMovement {
|
|
951
414
|
kind: "sweep" | "redeem";
|
|
952
415
|
vault: string;
|
|
@@ -1270,738 +733,110 @@ interface OrderScanner$1 {
|
|
|
1270
733
|
|
|
1271
734
|
/**
|
|
1272
735
|
* Per-instance event bus for one filler.
|
|
1273
|
-
*
|
|
1274
|
-
* This used to own a block-scan loop per chain. It no longer does: scanning is
|
|
1275
|
-
* identical work for every filler on a chain, so it moved to a shared
|
|
1276
|
-
* {@link OrderSource} and this class subscribes to it. Everything else stays —
|
|
1277
|
-
* the monitor is the filler's event bus, not merely a source. `IntentFiller`
|
|
1278
|
-
* emits `orderTiming`, `orderSkipped`, `orderFilled`, `orderExecuted` and
|
|
1279
|
-
* `rebalanceExecuted` on it, `ActivityRecorder` attaches to it, and `Simplex`
|
|
1280
|
-
* re-exposes it as the public event surface.
|
|
1281
|
-
*
|
|
1282
|
-
* Three things must stay on this side of the boundary:
|
|
1283
|
-
* - the `OrderFilled` filler-address filter. `filler` is `indexed: false` on
|
|
1284
|
-
* both `OrderFilled` and `PartialFill`, so it can never be a topic filter;
|
|
1285
|
-
* every consumer receives every fill and narrows it locally.
|
|
1286
|
-
* - the leg filter. An order reaches the filler only when its inputs and
|
|
1287
|
-
* outputs pair up leg by leg; the strategy then bids on each leg one of its
|
|
1288
|
-
* limit orders serves.
|
|
1289
|
-
* - de-duplication. Exactly-once used to be emergent — a private monotonic
|
|
1290
|
-
* cursor made a repeat impossible. A shared feed can replay from a cursor
|
|
1291
|
-
* after a reconnect, so the seen-set below is what preserves the property
|
|
1292
|
-
* the filler has always assumed.
|
|
1293
|
-
*/
|
|
1294
|
-
declare class EventMonitor extends EventEmitter {
|
|
1295
|
-
private listening;
|
|
1296
|
-
private configService;
|
|
1297
|
-
private fillerAddress;
|
|
1298
|
-
private logger;
|
|
1299
|
-
private orderScanner;
|
|
1300
|
-
private subscription?;
|
|
1301
|
-
/** Chain ids this filler is configured for; the scanner may carry more. */
|
|
1302
|
-
private chains;
|
|
1303
|
-
/** Order ids already delivered, newest last. Bounds the memory a replay can cost. */
|
|
1304
|
-
private seen;
|
|
1305
|
-
private seenOrder;
|
|
1306
|
-
constructor(chainConfigs: ChainConfig[], configService: FillerConfigService, fillerAddress: HexString, orderScanner: OrderScanner$1);
|
|
1307
|
-
/** Marks a chain as one this filler cares about. */
|
|
1308
|
-
private registerChain;
|
|
1309
|
-
/**
|
|
1310
|
-
* Attaches to the scanner. One subscription covers every chain it carries — a
|
|
1311
|
-
* scanner shared with other fillers may cover more chains than this one is
|
|
1312
|
-
* configured for, so events are matched on `chainId` here.
|
|
1313
|
-
*/
|
|
1314
|
-
startListening(): Promise<void>;
|
|
1315
|
-
private handleOrder;
|
|
1316
|
-
private handleFill;
|
|
1317
|
-
/**
|
|
1318
|
-
* Starts matching events for a chain added after boot.
|
|
1319
|
-
*
|
|
1320
|
-
* The scanner must already carry the chain. `Simplex` adds it to a scanner it
|
|
1321
|
-
* owns; when the scanner was supplied by the caller it stays the caller's to
|
|
1322
|
-
* manage, so that another filler reading from it is never surprised by a
|
|
1323
|
-
* chain appearing or vanishing underneath it.
|
|
1324
|
-
*/
|
|
1325
|
-
addChain(chainId: number): Promise<void>;
|
|
1326
|
-
/** Stops matching events for a chain. The scanner keeps scanning it for others. */
|
|
1327
|
-
removeChain(chainId: number): Promise<void>;
|
|
1328
|
-
/**
|
|
1329
|
-
* No-op against a scanner: endpoints belong to the scanner, not to a filler
|
|
1330
|
-
* reading from it. `Simplex.chains.setRpcUrls` swaps the endpoints on a scanner
|
|
1331
|
-
* it owns and rejects the call on one it does not.
|
|
1332
|
-
*/
|
|
1333
|
-
rebuildChain(chainId: number): Promise<void>;
|
|
1334
|
-
/** Events dropped because this filler could not keep up with the scanner. */
|
|
1335
|
-
droppedEvents(): number;
|
|
1336
|
-
stopListening(): Promise<void>;
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
/**
|
|
1340
|
-
* An execution outcome that can also report a still-pooled bid.
|
|
1341
|
-
*
|
|
1342
|
-
* `submitBid` can time out with the extrinsic still in Hyperbridge's pool. That
|
|
1343
|
-
* is neither success nor failure: the extrinsic may yet land and reserve a
|
|
1344
|
-
* deposit, so the bid record has to be reclaimable even though `success` is
|
|
1345
|
-
* false. Widened here rather than on the SDK's `ExecutionResult` so simplex does
|
|
1346
|
-
* not need an unreleased SDK.
|
|
1347
|
-
*/
|
|
1348
|
-
interface FillResult extends ExecutionResult {
|
|
1349
|
-
pending?: boolean;
|
|
1350
|
-
/**
|
|
1351
|
-
* The identifier Hyperbridge files the bid under, once its op was built:
|
|
1352
|
-
* `keccak256` of its calldata. It tells the bids on one order apart, and retracting the bid names it.
|
|
1353
|
-
*/
|
|
1354
|
-
bid?: HexString;
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
interface FillerStrategy {
|
|
1358
|
-
name: string;
|
|
1359
|
-
canFill(order: Order): Promise<boolean>;
|
|
1360
|
-
calculateProfitability(order: Order): Promise<number>;
|
|
1361
|
-
executeOrder(order: Order, hyperbridge?: IntentsCoprocessor): Promise<FillResult>;
|
|
1362
|
-
/**
|
|
1363
|
-
* Optional hook for strategies to provide a USD value for the full input basket.
|
|
1364
|
-
* Returns null when the strategy cannot or does not want to price the order.
|
|
1365
|
-
*/
|
|
1366
|
-
getOrderUsdValue?(order: Order): Promise<{
|
|
1367
|
-
inputUsd: Decimal;
|
|
1368
|
-
} | null>;
|
|
1369
|
-
/**
|
|
1370
|
-
* Optional confirmation policy for this strategy.
|
|
1371
|
-
* If absent, no confirmation waiting is required (e.g. same-chain strategies).
|
|
1372
|
-
*/
|
|
1373
|
-
confirmationPolicy?: {
|
|
1374
|
-
getConfirmationBlocks: (chainId: number, amountUsd: number) => number;
|
|
1375
|
-
};
|
|
1376
|
-
}
|
|
1377
|
-
|
|
1378
|
-
/**
|
|
1379
|
-
* A user-supplied asset entry in the `[assets]` TOML table: symbol → chain
|
|
1380
|
-
* state machine id → contract address.
|
|
1381
|
-
*
|
|
1382
|
-
* ```toml
|
|
1383
|
-
* [assets.BRZ]
|
|
1384
|
-
* "EVM-1" = "0x..."
|
|
1385
|
-
* "EVM-137" = "0x..."
|
|
1386
|
-
* ```
|
|
1387
|
-
*/
|
|
1388
|
-
type AssetDefinition = Record<string, HexString>;
|
|
1389
|
-
/**
|
|
1390
|
-
* The subset of `FillerConfigService` used to resolve built-in symbols to
|
|
1391
|
-
* per-chain addresses from the SDK chain registry.
|
|
1392
|
-
*/
|
|
1393
|
-
interface BuiltinAssetResolver {
|
|
1394
|
-
getUsdcAsset(chain: string): HexString;
|
|
1395
|
-
getUsdtAsset(chain: string): HexString;
|
|
1396
|
-
getDaiAsset(chain: string): HexString;
|
|
1397
|
-
getCNgnAsset(chain: string): HexString | undefined;
|
|
1398
|
-
/** Generic per-chain lookup into the SDK chain registry's asset table. */
|
|
1399
|
-
getAssetBySymbol(chain: string, symbol: string): HexString | undefined;
|
|
1400
|
-
}
|
|
1401
|
-
/**
|
|
1402
|
-
* Symbols pegged to 1 USD. They are pinned at $1 when an order's USD value is
|
|
1403
|
-
* derived from the limit orders' rates (see `usdFactorsFrom`), which is what
|
|
1404
|
-
* sizes confirmation depth. Trade pricing never uses this as a price.
|
|
1405
|
-
*/
|
|
1406
|
-
declare const USD_STABLE_SYMBOLS: ReadonlySet<string>;
|
|
1407
|
-
/** Normalises a symbol for lookups: trimmed, uppercased. "cNGN" ≡ "CNGN". */
|
|
1408
|
-
declare function normalizeSymbol(symbol: string): string;
|
|
1409
|
-
/** Every symbol the registry ships without user configuration. */
|
|
1410
|
-
declare function registrySymbols(): string[];
|
|
1411
|
-
/** Whether `symbol` ships with the registry (built-in or curated). Pure — no chain resolution. */
|
|
1412
|
-
declare function isRegistrySymbol(symbol: string): boolean;
|
|
1413
|
-
/**
|
|
1414
|
-
* Validates the `[assets]` table; throws a descriptive error on the first
|
|
1415
|
-
* invalid entry. Side-effect free — safe to call at config-parse time and again
|
|
1416
|
-
* at registry construction.
|
|
1417
|
-
*/
|
|
1418
|
-
declare function validateAssetDefinitions(assets: Record<string, AssetDefinition>): void;
|
|
1419
|
-
/**
|
|
1420
|
-
* Symbol → contract address registry backing the `[[pairs]]` configuration.
|
|
1421
|
-
*
|
|
1422
|
-
* Resolution merges two layers, most specific winning:
|
|
1423
|
-
* 1. the user's `[assets]` table — an *escape hatch* for assets the registry
|
|
1424
|
-
* doesn't ship (or per-deployment overrides), never required for shipped
|
|
1425
|
-
* symbols;
|
|
1426
|
-
* 2. shipped symbols (USDC, USDT, DAI, CNGN, USDR, ZARP, EURC, XSGD, TRYB,
|
|
1427
|
-
* BRIDGE) resolved per chain from the SDK chain registry (`chain.ts`) —
|
|
1428
|
-
* the single source of truth shared with the rest of the SDK, so an
|
|
1429
|
-
* address correction there is never shadowed by a parallel table here.
|
|
1430
|
-
*
|
|
1431
|
-
* Address lookups are per `(symbol, chain)` — a chain where no layer knows the
|
|
1432
|
-
* asset simply doesn't trade pairs involving it. The registry holds addresses
|
|
1433
|
-
* only; all pricing (including risk sizing) is derived from the pair curves.
|
|
1434
|
-
*/
|
|
1435
|
-
declare class AssetRegistry {
|
|
1436
|
-
private readonly resolver;
|
|
1437
|
-
private readonly userAssets;
|
|
1438
|
-
private readonly addressCache;
|
|
1439
|
-
constructor(resolver: BuiltinAssetResolver, userAssets?: Record<string, AssetDefinition>);
|
|
1440
|
-
/** Whether `symbol` is known (user-defined, curated, or built-in). */
|
|
1441
|
-
hasSymbol(symbol: string): boolean;
|
|
1442
|
-
/**
|
|
1443
|
-
* Registers new user-defined assets on the live registry (runtime market
|
|
1444
|
-
* adds). Existing symbols may not be redefined — an address swap under a
|
|
1445
|
-
* running market would silently repoint its fills.
|
|
1446
|
-
*/
|
|
1447
|
-
addAssets(defs: Record<string, AssetDefinition>): void;
|
|
1448
|
-
/**
|
|
1449
|
-
* Contract address of `symbol` on `chain`, or `null` when the asset is not
|
|
1450
|
-
* deployed/known there. User `[assets]` addresses win over the SDK chain
|
|
1451
|
-
* registry, per chain.
|
|
1452
|
-
*/
|
|
1453
|
-
getAddress(symbol: string, chain: string): HexString | null;
|
|
1454
|
-
/**
|
|
1455
|
-
* The symbol `address` is known by on `chain`, or null when nothing in the
|
|
1456
|
-
* registry resolves to it.
|
|
1457
|
-
*
|
|
1458
|
-
* Every symbol this registry can name is tried, user `[assets]` first so an
|
|
1459
|
-
* overridden address reports the name the operator gave it. Two symbols
|
|
1460
|
-
* resolving to one address would be a registry mistake; the first wins.
|
|
1461
|
-
*/
|
|
1462
|
-
symbolFor(address: string, chain: string): string | null;
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
/**
|
|
1466
|
-
* One market from the top-level `[[pairs]]` TOML array:
|
|
1467
|
-
*
|
|
1468
|
-
* ```toml
|
|
1469
|
-
* [[pairs]]
|
|
1470
|
-
* token0 = "USDC" # the book's base — any symbol in the asset registry
|
|
1471
|
-
* token1 = "CNGN" # the book's quote — any symbol in the asset registry
|
|
1472
|
-
* ```
|
|
1473
|
-
*
|
|
1474
|
-
* A pair declares that a market exists and nothing more. What the filler will
|
|
1475
|
-
* pay on it comes from the operator's limit orders, which carry the rate and the
|
|
1476
|
-
* size they are good for.
|
|
1477
|
-
*
|
|
1478
|
-
* The orientation follows the orderbook's books, which the setup wizard copies:
|
|
1479
|
-
* `token0` is the book's base and `token1` its quote, so the `USDC-cNGN` book
|
|
1480
|
-
* (priced in cNGN per USDC) becomes `token0 = "USDC"`, `token1 = "CNGN"`. One
|
|
1481
|
-
* orientation only: `A/B` and `B/A` are the same market and declaring both is
|
|
1482
|
-
* refused. `token0 == token1` is the same-asset cross-chain market.
|
|
1483
|
-
*/
|
|
1484
|
-
interface PairConfig {
|
|
1485
|
-
/** The book's base symbol (e.g. "USDC", "USDT"). Any symbol in the registry. */
|
|
1486
|
-
token0: string;
|
|
1487
|
-
/** The book's quote symbol, which the book prices the base in (e.g. "CNGN"). Any symbol in the registry. */
|
|
1488
|
-
token1: string;
|
|
1489
|
-
}
|
|
1490
|
-
/**
|
|
1491
|
-
* The USD stable to quote a reference feed against for an unanchored symbol:
|
|
1492
|
-
* the first stable (registry preference order) with no existing orientation
|
|
1493
|
-
* against it — a pair and its reverse are the same market, so a stable that
|
|
1494
|
-
* already has any market against the symbol cannot also carry the feed.
|
|
1495
|
-
* Returns null when every stable is taken. Shared by both wizards.
|
|
1496
|
-
*/
|
|
1497
|
-
declare function pickAnchorStable(pairs: Array<{
|
|
1498
|
-
token0: string;
|
|
1499
|
-
token1: string;
|
|
1500
|
-
}>, symbol: string): string | null;
|
|
1501
|
-
/**
|
|
1502
|
-
* Validates the `[[pairs]]` array against the `[assets]` table and built-in
|
|
1503
|
-
* symbols. Pure — throws a descriptive error on the first invalid pair.
|
|
1504
|
-
*/
|
|
1505
|
-
declare function validatePairConfigs(pairs: PairConfig[], userAssets?: Record<string, AssetDefinition>): void;
|
|
1506
|
-
|
|
1507
|
-
interface ChainBalanceRow {
|
|
1508
|
-
chainId: number;
|
|
1509
|
-
native?: {
|
|
1510
|
-
symbol: string;
|
|
1511
|
-
amount: number;
|
|
1512
|
-
};
|
|
1513
|
-
usdc?: number;
|
|
1514
|
-
usdt?: number;
|
|
1515
|
-
exotics?: Array<{
|
|
1516
|
-
symbol: string;
|
|
1517
|
-
amount: number;
|
|
1518
|
-
}>;
|
|
1519
|
-
/** Canonical token balances, including funds held in configured ERC-4626 vaults. */
|
|
1520
|
-
assets: AssetBalanceRow[];
|
|
1521
|
-
}
|
|
1522
|
-
type AssetBalanceStatus = "fresh" | "partial" | "unavailable";
|
|
1523
|
-
interface VaultBalanceRow {
|
|
1524
|
-
address: string;
|
|
1525
|
-
position: number;
|
|
1526
|
-
available: number;
|
|
1527
|
-
/** False while the vault reports `maxDeposit(solver) == 0`; sweeps into it are idle until it reopens. */
|
|
1528
|
-
acceptsDeposits: boolean;
|
|
1529
|
-
}
|
|
1530
|
-
interface AssetBalanceRow {
|
|
1531
|
-
address: string;
|
|
1532
|
-
symbol: string;
|
|
1533
|
-
/** Direct underlying balance held by the solver account. Null when its RPC read failed. */
|
|
1534
|
-
wallet: number | null;
|
|
1535
|
-
/** Configured wallet floor that must remain liquid. */
|
|
1536
|
-
walletReserve: number;
|
|
1537
|
-
/** Total solver-owned underlying represented by vault shares. */
|
|
1538
|
-
vaultPosition: number;
|
|
1539
|
-
/** Vault assets that can be withdrawn now, after pending-fill reservations. */
|
|
1540
|
-
vaultAvailable: number;
|
|
1541
|
-
/** Wallet plus vault position. Null when any required source was unavailable. */
|
|
1542
|
-
total: number | null;
|
|
1543
|
-
/** Spendable wallet above reserve plus currently withdrawable vault assets. */
|
|
1544
|
-
available: number | null;
|
|
1545
|
-
vaults: VaultBalanceRow[];
|
|
1546
|
-
status: AssetBalanceStatus;
|
|
1547
|
-
}
|
|
1548
|
-
type BalanceIssueSource = "chain" | "native" | "token" | "vault";
|
|
1549
|
-
interface BalanceIssue {
|
|
1550
|
-
chainId?: number;
|
|
1551
|
-
source: BalanceIssueSource;
|
|
1552
|
-
asset?: string;
|
|
1553
|
-
message: string;
|
|
1554
|
-
}
|
|
1555
|
-
type BalanceSnapshotStatus = "loading" | "fresh" | "partial" | "unavailable";
|
|
1556
|
-
interface HyperbridgeBalance {
|
|
1557
|
-
address: string;
|
|
1558
|
-
free: number;
|
|
1559
|
-
reserved: number;
|
|
1560
|
-
}
|
|
1561
|
-
interface BalanceSnapshot {
|
|
1562
|
-
/** null until the first refresh attempt completes. */
|
|
1563
|
-
updatedAt: number | null;
|
|
1564
|
-
status: BalanceSnapshotStatus;
|
|
1565
|
-
chains: ChainBalanceRow[];
|
|
1566
|
-
issues: BalanceIssue[];
|
|
1567
|
-
hyperbridge?: HyperbridgeBalance;
|
|
1568
|
-
}
|
|
1569
|
-
/** Narrow read-only seam implemented by the vault funding planner. */
|
|
1570
|
-
interface VaultBalanceSource {
|
|
1571
|
-
getBalanceSnapshot(chain?: string): Promise<VaultBalancePosition[]>;
|
|
1572
|
-
}
|
|
1573
|
-
interface BalanceProviderOptions {
|
|
1574
|
-
chainClientManager: ChainClientManager;
|
|
1575
|
-
configService: FillerConfigService;
|
|
1576
|
-
fillerAddress: string;
|
|
1577
|
-
/** Exotic token addresses per state machine id — every cross-asset pair's token1 on that chain. */
|
|
1578
|
-
token1: Record<string, string[]>;
|
|
1579
|
-
/**
|
|
1580
|
-
* The filler's Hyperbridge connection, reused rather than dialled again. A second socket to the
|
|
1581
|
-
* same node doubles the reconnect traffic during an outage for a balance read that is only
|
|
1582
|
-
* needed once a minute.
|
|
1583
|
-
*/
|
|
1584
|
-
hyperbridge?: Promise<IntentsCoprocessor>;
|
|
1585
|
-
substratePrivateKey?: string;
|
|
1586
|
-
refreshIntervalMs?: number;
|
|
1587
|
-
vaultBalances?: VaultBalanceSource;
|
|
1588
|
-
}
|
|
1589
|
-
/**
|
|
1590
|
-
* Periodically collects wallet balances (native, USDC, USDT, exotic per chain,
|
|
1591
|
-
* plus the BRIDGE balance of the substrate account) into a plain snapshot,
|
|
1592
|
-
* consumed by the UI JSON API and `wallet.balances()`.
|
|
1593
|
-
*/
|
|
1594
|
-
declare class BalanceProvider extends EventEmitter$1 {
|
|
1595
|
-
private snapshot;
|
|
1596
|
-
private stopped;
|
|
1597
|
-
private refreshInterval?;
|
|
1598
|
-
private hyperbridgeInterval?;
|
|
1599
|
-
private logger;
|
|
1600
|
-
private options;
|
|
1601
|
-
private intervalMs;
|
|
1602
|
-
constructor(options: BalanceProviderOptions);
|
|
1603
|
-
start(): Promise<void>;
|
|
1604
|
-
stop(): void;
|
|
1605
|
-
getSnapshot(): BalanceSnapshot;
|
|
1606
|
-
refresh(): Promise<BalanceSnapshot>;
|
|
1607
|
-
private collectChain;
|
|
1608
|
-
private addConfiguredStable;
|
|
1609
|
-
private trackHyperbridgeBalance;
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
/** The stretch of time a summary covers. Each is cut into buckets of one size. */
|
|
1613
|
-
type ProfitPeriod = "7d" | "30d" | "12w" | "12m" | "all";
|
|
1614
|
-
type ProfitBucket = "day" | "week" | "month" | "year";
|
|
1615
|
-
/** What a stretch of fills came to, in dollars at the latest rate. Unpriced tokens are left out. */
|
|
1616
|
-
interface ProfitFigures {
|
|
1617
|
-
/** What the stretch's fills added to inventory, less what they took out of it. */
|
|
1618
|
-
profitUsd: number;
|
|
1619
|
-
/** The inventory held when the stretch began. Null when nothing within reach of then records it. */
|
|
1620
|
-
startInventoryUsd: number | null;
|
|
1621
|
-
/** `profitUsd` over `startInventoryUsd`, as a percentage. Null without a starting inventory. */
|
|
1622
|
-
returnPct: number | null;
|
|
1623
|
-
/**
|
|
1624
|
-
* What moved in and out over the stretch other than through fills, net: deposits, withdrawals,
|
|
1625
|
-
* fees and vault yield. Null when the indexer has no reading for both ends of the stretch.
|
|
1626
|
-
*/
|
|
1627
|
-
transfersUsd: number | null;
|
|
1628
|
-
boughtUsd: number;
|
|
1629
|
-
soldUsd: number;
|
|
1630
|
-
buys: number;
|
|
1631
|
-
sells: number;
|
|
1632
|
-
}
|
|
1633
|
-
interface ProfitBucketFigures extends ProfitFigures {
|
|
1634
|
-
/** When the bucket starts, in milliseconds since the epoch. */
|
|
1635
|
-
start: number;
|
|
1636
|
-
}
|
|
1637
|
-
/** One book's buys against its sells over the period, in the book's own tokens. */
|
|
1638
|
-
interface BookProfit {
|
|
1639
|
-
book: string;
|
|
1640
|
-
base: string;
|
|
1641
|
-
quote: string;
|
|
1642
|
-
/** Base bought and sold in the period. */
|
|
1643
|
-
bought: number;
|
|
1644
|
-
sold: number;
|
|
1645
|
-
/** Quote per base, averaged over the period's buys and its sells. Null for a side with none. */
|
|
1646
|
-
averageBuy: number | null;
|
|
1647
|
-
averageSell: number | null;
|
|
1648
|
-
/** How far the average sell sits above the average buy, as a percentage. Null without both. */
|
|
1649
|
-
spreadPct: number | null;
|
|
1650
|
-
/** What the period's fills did to the base and the quote held: positive is more than before. */
|
|
1651
|
-
baseChange: number;
|
|
1652
|
-
quoteChange: number;
|
|
1653
|
-
/** The rate the book's tokens are valued at: midway between its latest buy and latest sell. */
|
|
1654
|
-
rate: number | null;
|
|
1655
|
-
/** Both changes in dollars. Null when the book's tokens have no dollar price. */
|
|
1656
|
-
profitUsd: number | null;
|
|
1657
|
-
}
|
|
1658
|
-
/** The inventory a period began with, token by token. */
|
|
1659
|
-
interface StartingInventory {
|
|
1660
|
-
/** The instant it describes, in milliseconds since the epoch. */
|
|
1661
|
-
at: number;
|
|
1662
|
-
/** A stored snapshot, or the balances as they stand now. Either is adjusted by what happened between. */
|
|
1663
|
-
source: "snapshot" | "balances";
|
|
1664
|
-
/** When that record was taken. */
|
|
1665
|
-
recordedAt: number;
|
|
1666
|
-
usd: number;
|
|
1667
|
-
tokens: Array<{
|
|
1668
|
-
symbol: string;
|
|
1669
|
-
amount: number;
|
|
1670
|
-
usd: number | null;
|
|
1671
|
-
}>;
|
|
1672
|
-
}
|
|
1673
|
-
interface Profitability {
|
|
1674
|
-
period: ProfitPeriod;
|
|
1675
|
-
bucket: ProfitBucket;
|
|
1676
|
-
/** The start of the first bucket and the moment the summary was taken, in milliseconds. */
|
|
1677
|
-
from: number;
|
|
1678
|
-
to: number;
|
|
1679
|
-
totals: ProfitFigures;
|
|
1680
|
-
/** One entry per bucket, oldest first, including buckets nothing happened in. */
|
|
1681
|
-
series: ProfitBucketFigures[];
|
|
1682
|
-
books: BookProfit[];
|
|
1683
|
-
/** Null when there is no snapshot, and the period began more than {@link BALANCES_REACH_MS} ago. */
|
|
1684
|
-
startInventory: StartingInventory | null;
|
|
1685
|
-
/** Fills in the period priced at their order's rate, because they kept no record of what they took in. */
|
|
1686
|
-
estimatedFills: number;
|
|
1687
|
-
/** Tokens the period touched that have no dollar price, and so are in none of the dollar figures. */
|
|
1688
|
-
unpricedTokens: string[];
|
|
1689
|
-
}
|
|
1690
|
-
|
|
1691
|
-
/**
|
|
1692
|
-
* Wire contracts between the UI server and the browser bundle. The server
|
|
1693
|
-
* types its response literals with these and `ui/src` imports them type-only,
|
|
1694
|
-
* so drift on either side is a compile error. Browser-safe: no runtime
|
|
1695
|
-
* dependencies beyond constants.
|
|
1696
|
-
*/
|
|
1697
|
-
|
|
1698
|
-
/** Signer work that must finish before the desktop may replace the bundled solver. */
|
|
1699
|
-
interface SolverWork {
|
|
1700
|
-
queuedEvaluations: number;
|
|
1701
|
-
evaluating: number;
|
|
1702
|
-
queuedFills: number;
|
|
1703
|
-
activeFills: number;
|
|
1704
|
-
retractions: number;
|
|
1705
|
-
rebalancing: number;
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
/** `[simplex.tunnel]` in the config file. */
|
|
1709
|
-
interface TunnelConfig {
|
|
1710
|
-
/** Off by default: enabling it makes the embedded SSH server reachable from the internet. */
|
|
1711
|
-
enabled?: boolean;
|
|
1712
|
-
/** `host[:port]`; port defaults to 443. */
|
|
1713
|
-
relay?: string;
|
|
1714
|
-
/** `SHA256:…` fingerprint of the relay host key. Without it the key seen on first contact is pinned. */
|
|
1715
|
-
relayHostKey?: string;
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
/**
|
|
1719
|
-
* A coordinate point on a curve
|
|
1720
|
-
* @property amount - The input threshold (e.g., USD amount)
|
|
1721
|
-
* @property value - The output value at this threshold (e.g., confirmations, bps)
|
|
1722
|
-
*/
|
|
1723
|
-
interface CurvePoint {
|
|
1724
|
-
amount: string;
|
|
1725
|
-
value: number;
|
|
1726
|
-
}
|
|
1727
|
-
/**
|
|
1728
|
-
* Configuration for a curve
|
|
1729
|
-
*/
|
|
1730
|
-
interface CurveConfig {
|
|
1731
|
-
points: CurvePoint[];
|
|
1732
|
-
}
|
|
1733
|
-
/**
|
|
1734
|
-
* Manages confirmation block requirements per chain.
|
|
1735
|
-
* Each chain has its own curve mapping order value to required confirmations.
|
|
1736
|
-
*/
|
|
1737
|
-
/**
|
|
1738
|
-
* Parses a per-chain config key. Every other table in the config writes chains
|
|
1739
|
-
* as state machine ids ("EVM-1"), so both "EVM-1" and bare "1" are accepted;
|
|
1740
|
-
* anything else returns null and callers MUST fail loudly — a silently
|
|
1741
|
-
* discarded chain key has meant committing capital on a chain configured as
|
|
1742
|
-
* watch-only, or hardening a confirmation curve that never applied.
|
|
736
|
+
*
|
|
737
|
+
* This used to own a block-scan loop per chain. It no longer does: scanning is
|
|
738
|
+
* identical work for every filler on a chain, so it moved to a shared
|
|
739
|
+
* {@link OrderSource} and this class subscribes to it. Everything else stays —
|
|
740
|
+
* the monitor is the filler's event bus, not merely a source. `IntentFiller`
|
|
741
|
+
* emits `orderTiming`, `orderSkipped`, `orderFilled`, `orderExecuted` and
|
|
742
|
+
* `rebalanceExecuted` on it, `ActivityRecorder` attaches to it, and `Simplex`
|
|
743
|
+
* re-exposes it as the public event surface.
|
|
744
|
+
*
|
|
745
|
+
* Three things must stay on this side of the boundary:
|
|
746
|
+
* - the `OrderFilled` filler-address filter. `filler` is `indexed: false` on
|
|
747
|
+
* both `OrderFilled` and `PartialFill`, so it can never be a topic filter;
|
|
748
|
+
* every consumer receives every fill and narrows it locally.
|
|
749
|
+
* - the leg filter. An order reaches the filler only when its inputs and
|
|
750
|
+
* outputs pair up leg by leg; the strategy then bids on each leg one of its
|
|
751
|
+
* limit orders serves.
|
|
752
|
+
* - de-duplication. Exactly-once used to be emergent — a private monotonic
|
|
753
|
+
* cursor made a repeat impossible. A shared feed can replay from a cursor
|
|
754
|
+
* after a reconnect, so the seen-set below is what preserves the property
|
|
755
|
+
* the filler has always assumed.
|
|
1743
756
|
*/
|
|
1744
|
-
declare
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
private
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
/**
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
*
|
|
1763
|
-
*
|
|
1764
|
-
* Used when a chain is added at runtime and covered by a built-in default: the
|
|
1765
|
-
* defaults are only materialised inside a freshly constructed policy, so the
|
|
1766
|
-
* live one adopts the entry rather than re-deriving it.
|
|
757
|
+
declare class EventMonitor extends EventEmitter$1 {
|
|
758
|
+
private listening;
|
|
759
|
+
private configService;
|
|
760
|
+
private fillerAddress;
|
|
761
|
+
private logger;
|
|
762
|
+
private orderScanner;
|
|
763
|
+
private subscription?;
|
|
764
|
+
/** Chain ids this filler is configured for; the scanner may carry more. */
|
|
765
|
+
private chains;
|
|
766
|
+
/** Order ids already delivered, newest last. Bounds the memory a replay can cost. */
|
|
767
|
+
private seen;
|
|
768
|
+
private seenOrder;
|
|
769
|
+
constructor(chainConfigs: ChainConfig[], configService: FillerConfigService, fillerAddress: HexString, orderScanner: OrderScanner$1);
|
|
770
|
+
/** Marks a chain as one this filler cares about. */
|
|
771
|
+
private registerChain;
|
|
772
|
+
/**
|
|
773
|
+
* Attaches to the scanner. One subscription covers every chain it carries — a
|
|
774
|
+
* scanner shared with other fillers may cover more chains than this one is
|
|
775
|
+
* configured for, so events are matched on `chainId` here.
|
|
1767
776
|
*/
|
|
1768
|
-
|
|
777
|
+
startListening(): Promise<void>;
|
|
778
|
+
private handleOrder;
|
|
779
|
+
private handleFill;
|
|
1769
780
|
/**
|
|
1770
|
-
*
|
|
1771
|
-
*
|
|
1772
|
-
*
|
|
781
|
+
* Starts matching events for a chain added after boot.
|
|
782
|
+
*
|
|
783
|
+
* The scanner must already carry the chain. `Simplex` adds it to a scanner it
|
|
784
|
+
* owns; when the scanner was supplied by the caller it stays the caller's to
|
|
785
|
+
* manage, so that another filler reading from it is never surprised by a
|
|
786
|
+
* chain appearing or vanishing underneath it.
|
|
1773
787
|
*/
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
interface PaymasterKeeperConfig {
|
|
1778
|
-
/** Chains to monitor. Defaults to every configured chain with a SimplexPaymaster. */
|
|
1779
|
-
chains?: string[];
|
|
1780
|
-
intervalMinutes?: number;
|
|
1781
|
-
/** Minimum accrued balance (in whole stablecoin units) worth recycling. */
|
|
1782
|
-
minSwapUsd?: number;
|
|
1783
|
-
}
|
|
1784
|
-
|
|
1785
|
-
interface ChainConfirmationPolicy {
|
|
788
|
+
addChain(chainId: number): Promise<void>;
|
|
789
|
+
/** Stops matching events for a chain. The scanner keeps scanning it for others. */
|
|
790
|
+
removeChain(chainId: number): Promise<void>;
|
|
1786
791
|
/**
|
|
1787
|
-
*
|
|
1788
|
-
*
|
|
792
|
+
* No-op against a scanner: endpoints belong to the scanner, not to a filler
|
|
793
|
+
* reading from it. `Simplex.chains.setRpcUrls` swaps the endpoints on a scanner
|
|
794
|
+
* it owns and rejects the call on one it does not.
|
|
1789
795
|
*/
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
}
|
|
1795
|
-
/**
|
|
1796
|
-
* TOML row for an ERC-4626 vault entry. `threshold` (absolute human units) is the
|
|
1797
|
-
* high-water mark that triggers a sweep down to `minBalance`; omit both for
|
|
1798
|
-
* withdraw-only sourcing.
|
|
1799
|
-
*/
|
|
1800
|
-
interface VaultToml {
|
|
1801
|
-
chain: string;
|
|
1802
|
-
vault: HexString;
|
|
1803
|
-
threshold?: string;
|
|
1804
|
-
minBalance?: string;
|
|
1805
|
-
redeemOnShutdown?: boolean;
|
|
1806
|
-
}
|
|
1807
|
-
/** Top-level `[vault]` config: ERC-4626 treasury vaults, for withdraw sourcing and threshold sweeping. */
|
|
1808
|
-
interface VaultTomlConfig {
|
|
1809
|
-
vaults?: VaultToml[];
|
|
1810
|
-
sweepIntervalMs?: number;
|
|
1811
|
-
}
|
|
1812
|
-
interface QueueConfig {
|
|
1813
|
-
maxRechecks: number;
|
|
1814
|
-
recheckDelayMs: number;
|
|
1815
|
-
}
|
|
1816
|
-
interface RebalancingConfig {
|
|
1817
|
-
triggerPercentage: number;
|
|
1818
|
-
baseBalances: {
|
|
1819
|
-
USDC?: Record<string, string>;
|
|
1820
|
-
USDT?: Record<string, string>;
|
|
1821
|
-
};
|
|
1822
|
-
}
|
|
1823
|
-
interface BinanceConfig {
|
|
1824
|
-
apiKey: string;
|
|
1825
|
-
apiSecret: string;
|
|
1826
|
-
basePath?: string;
|
|
1827
|
-
timeout?: number;
|
|
1828
|
-
depositTimeoutMs?: number;
|
|
1829
|
-
pollIntervalMs?: number;
|
|
1830
|
-
withdrawTimeoutMs?: number;
|
|
1831
|
-
}
|
|
1832
|
-
interface FillerTomlConfig {
|
|
1833
|
-
/**
|
|
1834
|
-
* Optional asset-registry escape hatch: symbol → { chain → address }. Only
|
|
1835
|
-
* needed for assets the built-in registry does not ship, or to override a
|
|
1836
|
-
* shipped address for a deployment. Shipped symbols: USDC, USDT, DAI, CNGN
|
|
1837
|
-
* (SDK chain registry) + curated USDR, ZARP, EURC, XSGD, TRYB and BRIDGE.
|
|
1838
|
-
*/
|
|
1839
|
-
assets?: Record<string, AssetDefinition>;
|
|
1840
|
-
/**
|
|
1841
|
-
* Markets the operator dashboard lists, as `token0`/`token1` symbol pairs.
|
|
1842
|
-
* They carry no prices and do not gate matching: the filler prices every
|
|
1843
|
-
* fill from the operator's limit orders. Optional; the browser setup wizard
|
|
1844
|
-
* writes one per book the orderbook lists. Keys left over from the curve
|
|
1845
|
-
* era (`bidPriceCurve`, `askPriceCurve`, `maxOrderSize`, `referenceOnly`)
|
|
1846
|
-
* are ignored.
|
|
1847
|
-
*/
|
|
1848
|
-
pairs?: PairConfig[];
|
|
1849
|
-
/**
|
|
1850
|
-
* Per-chain confirmation policies for cross-chain orders, keyed by chain id.
|
|
1851
|
-
* Merged over built-in defaults (ETH, BSC, Polygon, Base, Arbitrum,
|
|
1852
|
-
* Unichain); every configured chain must be covered or startup fails. The
|
|
1853
|
-
* policy's amount axis is the order's USD value: USD stables count at $1 and
|
|
1854
|
-
* other tokens are valued through the open limit orders' rates. An order no
|
|
1855
|
-
* limit order connects to a dollar waits for the policy's maximum depth.
|
|
1856
|
-
*/
|
|
1857
|
-
confirmationPolicies?: Record<string, ChainConfirmationPolicy>;
|
|
1858
|
-
simplex: {
|
|
1859
|
-
/** Orders evaluated at once. Defaults to 5. */
|
|
1860
|
-
maxConcurrentOrders?: number;
|
|
1861
|
-
/**
|
|
1862
|
-
* Accepted and ignored. Older configs and the wizard used to write it; the
|
|
1863
|
-
* engine never read it. Kept in the type so those configs still load.
|
|
1864
|
-
*/
|
|
1865
|
-
queue?: QueueConfig;
|
|
1866
|
-
logging?: string;
|
|
1867
|
-
watchOnly?: boolean | Record<string, boolean>;
|
|
1868
|
-
substratePrivateKey: string;
|
|
1869
|
-
hyperbridgeWsUrl: string;
|
|
1870
|
-
/**
|
|
1871
|
-
* Hyperbridge indexer GraphQL endpoint, used to backfill order details on
|
|
1872
|
-
* activity rows recorded before they were captured. Defaults per network
|
|
1873
|
-
* (nexus for mainnet, gargantua for testnet).
|
|
1874
|
-
*/
|
|
1875
|
-
indexerUrl?: string;
|
|
1876
|
-
/** Accepted and ignored. Contract addresses come from the SDK chain registry. */
|
|
1877
|
-
entryPointAddress?: string;
|
|
1878
|
-
/** Accepted and ignored. Contract addresses come from the SDK chain registry. */
|
|
1879
|
-
solverAccountContractAddress?: string;
|
|
1880
|
-
/** Target gas units for EntryPoint deposits per chain. Defaults to 3,000,000. */
|
|
1881
|
-
targetGasUnits?: number;
|
|
1882
|
-
/**
|
|
1883
|
-
* Block-scanner poll period per chain in seconds. Defaults to 3, and
|
|
1884
|
-
* fractional values are allowed (0.5 = twice a second). Each tick costs
|
|
1885
|
-
* one `eth_blockNumber` + one `eth_getLogs` per chain per endpoint, so
|
|
1886
|
-
* raising this is the lever for fitting inside a rate-limited RPC's
|
|
1887
|
-
* budget; the cost is seeing new orders that much later.
|
|
1888
|
-
*/
|
|
1889
|
-
blockScanIntervalSeconds?: number;
|
|
1890
|
-
/** Gas fee bump (percentages added to base gasPrice). Defaults: priority=8%, max=10%. */
|
|
1891
|
-
gasFeeBump?: {
|
|
1892
|
-
maxPriorityFeePerGasBumpPercent?: number;
|
|
1893
|
-
maxFeePerGasBumpPercent?: number;
|
|
1894
|
-
};
|
|
1895
|
-
/**
|
|
1896
|
-
* Overfill protection knobs. Defaults: maxOverfillBps=500, maxConsecutiveClamps=3.
|
|
1897
|
-
* `maxOverfillBps` is warn-only: FXFiller logs a limit order whose offer exceeds
|
|
1898
|
-
* the swapper's ask by more than this, and clamps nothing. `maxConsecutiveClamps`
|
|
1899
|
-
* is accepted but dormant: the clamp that fed it was for Uniswap V4 venue pricing,
|
|
1900
|
-
* which is gone, so FXFiller never halts.
|
|
1901
|
-
*/
|
|
1902
|
-
overfillProtection?: {
|
|
1903
|
-
maxOverfillBps?: number;
|
|
1904
|
-
maxConsecutiveClamps?: number;
|
|
1905
|
-
};
|
|
1906
|
-
/**
|
|
1907
|
-
* How long a signed bid stays executable, in seconds. Defaults to 300 (5 minutes).
|
|
1908
|
-
*
|
|
1909
|
-
* Written into `FillOptions.validUntil` and enforced by `fillOrder`, which reverts
|
|
1910
|
-
* `FillExpired` past it. This is how long the quoted price stands as a firm commitment:
|
|
1911
|
-
* the order's `deadline` is chosen by the placer with no ceiling, and retracting the bid
|
|
1912
|
-
* on Hyperbridge does not reach the destination chain, so without it a signed bid stays
|
|
1913
|
-
* executable indefinitely and is taken up only once the rate has moved against us.
|
|
1914
|
-
*
|
|
1915
|
-
* Configured in seconds but written on-chain in blocks, converted per destination chain.
|
|
1916
|
-
*/
|
|
1917
|
-
bidValiditySeconds?: number;
|
|
1918
|
-
/**
|
|
1919
|
-
* The order size, in USD, below which `order.fees` must cover the execution cost
|
|
1920
|
-
* (fill gas plus, cross-chain, the relayer fee). Defaults to 20.
|
|
1921
|
-
*
|
|
1922
|
-
* An order worth at least this much is filled whatever fees it carries: the margin
|
|
1923
|
-
* in the limit order that prices it pays for the gas. On a smaller order that
|
|
1924
|
-
* margin is too thin to, so the fees have to. Set to 0 to never check fees. An
|
|
1925
|
-
* order nothing can put a dollar figure on is treated as below it.
|
|
1926
|
-
*/
|
|
1927
|
-
minOrderSizeUsd?: number;
|
|
1928
|
-
/**
|
|
1929
|
-
* Remote access: an outbound SSH tunnel to a rendezvous relay so a phone's
|
|
1930
|
-
* SSH client can reach the local web UI. Off unless `enabled = true`; the
|
|
1931
|
-
* relay defaults to the hosted one. Devices are paired from the UI.
|
|
1932
|
-
*/
|
|
1933
|
-
tunnel?: TunnelConfig;
|
|
1934
|
-
};
|
|
1935
|
-
chains: UserProvidedChainConfig[];
|
|
1936
|
-
rebalancing?: RebalancingConfig;
|
|
1937
|
-
binance?: BinanceConfig;
|
|
1938
|
-
/** Filler-wide vault config: stablecoin sourcing for fills + threshold sweeping. */
|
|
1939
|
-
vault?: VaultTomlConfig;
|
|
1940
|
-
/** Restricts order processing to listed user addresses. Omit to accept all users. */
|
|
1941
|
-
allowlist?: AllowlistConfig;
|
|
1942
|
-
/** SimplexPaymaster fee-recycling keeper (`paymaster-keeper` subcommand). */
|
|
1943
|
-
keeper?: PaymasterKeeperConfig;
|
|
1944
|
-
/** The HyperFX orderbook simplex posts its limit orders to. */
|
|
1945
|
-
orderbook?: OrderbookConfig;
|
|
796
|
+
rebuildChain(chainId: number): Promise<void>;
|
|
797
|
+
/** Events dropped because this filler could not keep up with the scanner. */
|
|
798
|
+
droppedEvents(): number;
|
|
799
|
+
stopListening(): Promise<void>;
|
|
1946
800
|
}
|
|
801
|
+
|
|
1947
802
|
/**
|
|
1948
|
-
*
|
|
803
|
+
* An execution outcome that can also report a still-pooled bid.
|
|
1949
804
|
*
|
|
1950
|
-
*
|
|
1951
|
-
*
|
|
1952
|
-
*
|
|
805
|
+
* `submitBid` can time out with the extrinsic still in Hyperbridge's pool. That
|
|
806
|
+
* is neither success nor failure: the extrinsic may yet land and reserve a
|
|
807
|
+
* deposit, so the bid record has to be reclaimable even though `success` is
|
|
808
|
+
* false. Widened here rather than on the SDK's `ExecutionResult` so simplex does
|
|
809
|
+
* not need an unreleased SDK.
|
|
1953
810
|
*/
|
|
1954
|
-
interface
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
*
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
* clock, and nothing renews it.
|
|
1962
|
-
*/
|
|
1963
|
-
defaultTtlSecs?: number;
|
|
1964
|
-
/** How often to reconcile local limit orders against the orderbook, in seconds. */
|
|
1965
|
-
reconcileIntervalSecs?: number;
|
|
1966
|
-
requestTimeoutMs?: number;
|
|
811
|
+
interface FillResult extends ExecutionResult {
|
|
812
|
+
pending?: boolean;
|
|
813
|
+
/**
|
|
814
|
+
* The identifier Hyperbridge files the bid under, once its op was built:
|
|
815
|
+
* `keccak256` of its calldata. It tells the bids on one order apart, and retracting the bid names it.
|
|
816
|
+
*/
|
|
817
|
+
bid?: HexString;
|
|
1967
818
|
}
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
819
|
+
|
|
820
|
+
interface FillerStrategy {
|
|
821
|
+
name: string;
|
|
822
|
+
canFill(order: Order): Promise<boolean>;
|
|
823
|
+
calculateProfitability(order: Order): Promise<number>;
|
|
824
|
+
executeOrder(order: Order, hyperbridge?: IntentsCoprocessor): Promise<FillResult>;
|
|
825
|
+
/**
|
|
826
|
+
* Optional hook for strategies to provide a USD value for the full input basket.
|
|
827
|
+
* Returns null when the strategy cannot or does not want to price the order.
|
|
828
|
+
*/
|
|
829
|
+
getOrderUsdValue?(order: Order): Promise<{
|
|
830
|
+
inputUsd: Decimal;
|
|
831
|
+
} | null>;
|
|
832
|
+
/**
|
|
833
|
+
* Optional confirmation policy for this strategy.
|
|
834
|
+
* If absent, no confirmation waiting is required (e.g. same-chain strategies).
|
|
835
|
+
*/
|
|
836
|
+
confirmationPolicy?: {
|
|
837
|
+
getConfirmationBlocks: (chainId: number, amountUsd: number) => number;
|
|
1982
838
|
};
|
|
1983
839
|
}
|
|
1984
|
-
/**
|
|
1985
|
-
* Boot-parity confirmation coverage: every configured chain id needs a
|
|
1986
|
-
* confirmation curve (built-in defaults or [confirmationPolicies]), or orders
|
|
1987
|
-
* sourced on it would be silently dropped. Boot and both wizard write gates
|
|
1988
|
-
* run the same construction; the gates know the chain ids the wizard selected,
|
|
1989
|
-
* boot the ids resolved from the RPCs.
|
|
1990
|
-
*/
|
|
1991
|
-
declare function assertConfirmationCoverage(confirmationPolicies: FillerTomlConfig["confirmationPolicies"], chainIds: number[]): ConfirmationPolicy;
|
|
1992
|
-
/**
|
|
1993
|
-
* Validates raw TOML `[vault].vaults` entries. Pure and browser-safe — shared
|
|
1994
|
-
* by `validateConfig`, the vault-update endpoint and the funding planner.
|
|
1995
|
-
* Throws on missing/invalid required fields.
|
|
1996
|
-
*/
|
|
1997
|
-
declare function validateVaultToml(vaults: {
|
|
1998
|
-
chain?: string;
|
|
1999
|
-
vault?: string;
|
|
2000
|
-
threshold?: string;
|
|
2001
|
-
minBalance?: string;
|
|
2002
|
-
redeemOnShutdown?: boolean;
|
|
2003
|
-
}[]): void;
|
|
2004
|
-
declare function validateConfig(config: FillerTomlConfig, cliWatchOnly?: boolean): void;
|
|
2005
840
|
|
|
2006
841
|
/** Symbol and decimals for a token on a chain, as far as the filler knows them. */
|
|
2007
842
|
interface TokenDescription {
|
|
@@ -2030,7 +865,7 @@ interface ActivityRecorderOptions {
|
|
|
2030
865
|
* stored row is re-emitted as `event` for live consumers (the UI's SSE stream,
|
|
2031
866
|
* and `Simplex`'s `activity` event).
|
|
2032
867
|
*/
|
|
2033
|
-
declare class ActivityRecorder extends EventEmitter
|
|
868
|
+
declare class ActivityRecorder extends EventEmitter {
|
|
2034
869
|
private store;
|
|
2035
870
|
private logger;
|
|
2036
871
|
private monitor?;
|
|
@@ -2070,19 +905,6 @@ declare class ActivityRecorder extends EventEmitter$1 {
|
|
|
2070
905
|
walletTxs(limit?: number): Promise<WalletTx[]>;
|
|
2071
906
|
}
|
|
2072
907
|
|
|
2073
|
-
/** One market the engine serves, as the operator's market list shows it. */
|
|
2074
|
-
interface AdminStrategy {
|
|
2075
|
-
/** Stable identifier for the API. */
|
|
2076
|
-
index: number;
|
|
2077
|
-
/** Position in the TOML `[[pairs]]` array. */
|
|
2078
|
-
pairIndex: number;
|
|
2079
|
-
/** Pair label, e.g. "USDC/CNGN" (display-only). */
|
|
2080
|
-
exotic?: string;
|
|
2081
|
-
token0: string;
|
|
2082
|
-
token1: string;
|
|
2083
|
-
/** Same-asset cross-chain market, where the spread is realized in kind. */
|
|
2084
|
-
sameToken?: boolean;
|
|
2085
|
-
}
|
|
2086
908
|
/** Self-halt visibility/reset for one FX strategy (overfill protection). */
|
|
2087
909
|
interface HaltControl {
|
|
2088
910
|
index: number;
|
|
@@ -2488,111 +1310,6 @@ declare class ContractInteractionService {
|
|
|
2488
1310
|
buildApprovalAndFillCalldata(order: Order, fillerOutputs: TokenInfo[], fillOptions: FillOptions, requiredFeeTokenAmount: bigint, settlement?: BudgetSettlement): Promise<HexString>;
|
|
2489
1311
|
}
|
|
2490
1312
|
|
|
2491
|
-
/**
|
|
2492
|
-
* Service for managing EIP-7702 delegation of the filler's EOA to the SolverAccount contract.
|
|
2493
|
-
* This enables the filler to participate in solver selection mode.
|
|
2494
|
-
*
|
|
2495
|
-
* When the Simplex paymaster is configured and the filler holds stablecoins already
|
|
2496
|
-
* approved to Permit2, delegation is performed via a no-op UserOp sent through the
|
|
2497
|
-
* bundler — the paymaster pays gas in stablecoins. Falls back to a direct type-0x04 tx
|
|
2498
|
-
* if the bundler path is unavailable.
|
|
2499
|
-
*
|
|
2500
|
-
* The paymaster prefunds through Permit2, which needs a standing token approval to the
|
|
2501
|
-
* Permit2 contract. On a chain the solver has never used, the delegation op installs
|
|
2502
|
-
* that approval itself and pays for the privilege with an EIP-2612 permit, so a
|
|
2503
|
-
* permit-capable fee token bootstraps with no native at all. A token without a permit
|
|
2504
|
-
* (BNB Chain) still needs native dust once, for the type-0x04 tx that batches the
|
|
2505
|
-
* approve in. Every op after that is native-free either way.
|
|
2506
|
-
*/
|
|
2507
|
-
declare class DelegationService {
|
|
2508
|
-
private clientManager;
|
|
2509
|
-
private configService;
|
|
2510
|
-
private signer;
|
|
2511
|
-
private logger;
|
|
2512
|
-
private readonly userOpSender;
|
|
2513
|
-
constructor(clientManager: ChainClientManager, configService: FillerConfigService, signer: Signer);
|
|
2514
|
-
/**
|
|
2515
|
-
* @param viaBundler When true, uses the current nonce (bundler submits the tx).
|
|
2516
|
-
* When false, uses nonce+1 (EOA submits the type-0x04 tx itself).
|
|
2517
|
-
*/
|
|
2518
|
-
private buildAuthorization;
|
|
2519
|
-
private sendDelegationTransaction;
|
|
2520
|
-
/**
|
|
2521
|
-
* Best-effort resolution of a Permit2 approval to fold into a native delegation. Never
|
|
2522
|
-
* throws: a resolution failure (RPC error, misconfig) yields null and the delegation
|
|
2523
|
-
* proceeds as a plain self-call.
|
|
2524
|
-
*/
|
|
2525
|
-
private resolvePendingPermit2Approval;
|
|
2526
|
-
/**
|
|
2527
|
-
* Checks if the filler's EOA is already delegated to the SolverAccount contract on a specific chain.
|
|
2528
|
-
*/
|
|
2529
|
-
isDelegated(chain: string): Promise<boolean>;
|
|
2530
|
-
/**
|
|
2531
|
-
* Sets up EIP-7702 delegation via the bundler. Uses the Simplex paymaster when
|
|
2532
|
-
* configured and the filler holds a sufficient stablecoin balance.
|
|
2533
|
-
*
|
|
2534
|
-
* The op is a no-op once the account has a Permit2 allowance. On a chain it has
|
|
2535
|
-
* never used, and only when the fee token implements EIP-2612 (`permitCapable`),
|
|
2536
|
-
* the op instead carries `approve(Permit2, max)` as its callData and asks the
|
|
2537
|
-
* paymaster for PERMIT mode: the permit covers this op's gas, and the op installs
|
|
2538
|
-
* the allowance every later op authorizes against. That is the whole zero-native
|
|
2539
|
-
* bootstrap — one sponsored op, after which the account never needs a permit again.
|
|
2540
|
-
*/
|
|
2541
|
-
private setupDelegationViaBundler;
|
|
2542
|
-
/**
|
|
2543
|
-
* Installs `approve(Permit2, max)` on an account that is ALREADY delegated, using the same
|
|
2544
|
-
* permit-funded op the first-time delegation carries — minus the authorization, which it
|
|
2545
|
-
* does not need.
|
|
2546
|
-
*
|
|
2547
|
-
* This exists because delegation and bootstrap are separate facts. An account delegated by
|
|
2548
|
-
* an earlier release has no Permit2 allowance (that release charged EIP-2612 permits and
|
|
2549
|
-
* never touched Permit2), and `setupDelegation` returns before the bootstrap once
|
|
2550
|
-
* `isDelegated` holds. Leaving it there strands every upgraded solver on the native-funded
|
|
2551
|
-
* approve path.
|
|
2552
|
-
*
|
|
2553
|
-
* Best-effort and never throws: on failure the first sponsored op still falls back to
|
|
2554
|
-
* `sendFundedApprove`, which works for a solver holding native.
|
|
2555
|
-
*/
|
|
2556
|
-
private ensurePermit2Allowance;
|
|
2557
|
-
/**
|
|
2558
|
-
* Sets up EIP-7702 delegation from the filler's EOA to the SolverAccount contract.
|
|
2559
|
-
*
|
|
2560
|
-
* A fee token with no Permit2 allowance yet cannot be charged through Permit2, so the
|
|
2561
|
-
* approve has to be installed by the very first operation. Which carrier does that
|
|
2562
|
-
* depends on the token:
|
|
2563
|
-
*
|
|
2564
|
-
* - EIP-2612 token: the bundler goes first and the op pays for itself with a permit
|
|
2565
|
-
* while carrying the approve in its callData. No native is spent, so this is
|
|
2566
|
-
* preferred even on an EOA that holds some.
|
|
2567
|
-
* - No permit (BSC pegged stables): only a native type-0x04 tx can carry the approve,
|
|
2568
|
-
* so that goes first when the EOA covers it.
|
|
2569
|
-
*
|
|
2570
|
-
* With nothing pending — the allowance is already in place — the bundler path goes
|
|
2571
|
-
* first as usual. A plain direct tx is the last fallback in every case.
|
|
2572
|
-
*/
|
|
2573
|
-
setupDelegation(chain: string): Promise<boolean>;
|
|
2574
|
-
/** Whether the EOA can pay for one direct set-code tx at the current gas price. */
|
|
2575
|
-
private nativeCoversDirectTx;
|
|
2576
|
-
/**
|
|
2577
|
-
* Sends one native EIP-7702 delegation tx (optionally batching a Permit2 approve) and
|
|
2578
|
-
* waits for its receipt. Never throws: a revert or send error is logged and returns
|
|
2579
|
-
* false, so the caller can fall back. Rebuilds the authorization each call, so a fresh
|
|
2580
|
-
* nonce is used after a prior attempt consumed one.
|
|
2581
|
-
*/
|
|
2582
|
-
private trySendDelegation;
|
|
2583
|
-
/**
|
|
2584
|
-
* Sets up delegation on the specified chains where solver selection is active.
|
|
2585
|
-
*/
|
|
2586
|
-
setupDelegationOnChains(chains: string[]): Promise<{
|
|
2587
|
-
success: boolean;
|
|
2588
|
-
results: Record<string, boolean>;
|
|
2589
|
-
}>;
|
|
2590
|
-
/**
|
|
2591
|
-
* Revokes delegation by delegating to the zero address.
|
|
2592
|
-
*/
|
|
2593
|
-
revokeDelegation(chain: string): Promise<boolean>;
|
|
2594
|
-
}
|
|
2595
|
-
|
|
2596
1313
|
interface BinanceCexConfig {
|
|
2597
1314
|
apiKey: string;
|
|
2598
1315
|
apiSecret: string;
|
|
@@ -3432,7 +2149,7 @@ declare class IntentFiller {
|
|
|
3432
2149
|
private signer;
|
|
3433
2150
|
private fillerAddress;
|
|
3434
2151
|
private logger;
|
|
3435
|
-
constructor(chainConfigs: ChainConfig[], strategies: FillerStrategy[], config: FillerConfig
|
|
2152
|
+
constructor(chainConfigs: ChainConfig[], strategies: FillerStrategy[], config: FillerConfig, configService: FillerConfigService, chainClientManager: ChainClientManager, contractService: ContractInteractionService, signer: Signer, scanners: {
|
|
3436
2153
|
orders: OrderScanner$1;
|
|
3437
2154
|
}, rebalancingService?: RebalancingService, bidStorage?: BidStore, limitOrders?: LimitOrderStore, assetRegistry?: AssetRegistry);
|
|
3438
2155
|
/**
|
|
@@ -3640,278 +2357,11 @@ declare class IntentFiller {
|
|
|
3640
2357
|
private retractStoredBids;
|
|
3641
2358
|
}
|
|
3642
2359
|
|
|
3643
|
-
/**
|
|
3644
|
-
* One market the engine will quote, as a pair of registry symbols.
|
|
3645
|
-
*
|
|
3646
|
-
* A pair declares that the market exists and nothing more: what the filler pays
|
|
3647
|
-
* on it comes from the operator's limit orders. `token0 == token1` is the
|
|
3648
|
-
* same-asset cross-chain market, where the spread is realized in kind.
|
|
3649
|
-
*/
|
|
3650
|
-
interface TradingPair {
|
|
3651
|
-
token0: string;
|
|
3652
|
-
token1: string;
|
|
3653
|
-
}
|
|
3654
|
-
/**
|
|
3655
|
-
* Strategy for swaps priced by the operator's limit orders. Supports both
|
|
3656
|
-
* same-chain and cross-chain orders.
|
|
3657
|
-
*
|
|
3658
|
-
* Every leg is matched against the open limit orders (`matchLimitOrders`): an
|
|
3659
|
-
* order serves a leg when it fills on the destination chain, takes the leg's
|
|
3660
|
-
* input, pays out its output, accepts its source chain and, at its own rate,
|
|
3661
|
-
* pays at least what the swapper asked for. Each matching order gets its own
|
|
3662
|
-
* bid, best offer first, sized `min(offer, remaining)`; there is no fallback
|
|
3663
|
-
* price, so a leg nothing matches is not bid on. No external price feed is
|
|
3664
|
-
* consulted. Confirmation sizing is the only place a dollar value is needed,
|
|
3665
|
-
* and it is derived from the limit orders' own rates (see `usdFactorsFrom`).
|
|
3666
|
-
*
|
|
3667
|
-
* Payouts are bounded by the filler's real balances plus funding-venue
|
|
3668
|
-
* withdrawals. Because the IntentGateway releases inputs proportionally to the
|
|
3669
|
-
* fraction of outputs provided, partial fills need no extra on-chain logic.
|
|
3670
|
-
*
|
|
3671
|
-
* `[[pairs]]` markets do not gate matching; they name the markets the operator
|
|
3672
|
-
* dashboard lists.
|
|
3673
|
-
*/
|
|
3674
|
-
declare class FXFiller implements FillerStrategy {
|
|
3675
|
-
name: string;
|
|
3676
|
-
private clientManager;
|
|
3677
|
-
private contractService;
|
|
3678
|
-
private configService;
|
|
3679
|
-
/** Markets the dashboard lists. Informational only: matching reads the limit orders. */
|
|
3680
|
-
private pairs;
|
|
3681
|
-
/** Symbol → per-chain address resolution (built-ins + curated + user `[assets]`). */
|
|
3682
|
-
private registry;
|
|
3683
|
-
private signer;
|
|
3684
|
-
private logger;
|
|
3685
|
-
/**
|
|
3686
|
-
* Consecutive orders where the overfill clamp activated. Dormant: the clamp
|
|
3687
|
-
* existed for venue-priced legs, which went with Uniswap V4 pricing, so every
|
|
3688
|
-
* outcome is now recorded unclamped and this never climbs. See `recordOrderOutcome`.
|
|
3689
|
-
*/
|
|
3690
|
-
private consecutiveClamps;
|
|
3691
|
-
/** Once set, the filler refuses all orders until reset. Unreachable while the clamp is dormant. */
|
|
3692
|
-
private halted;
|
|
3693
|
-
/** Bps above the swapper's ask past which a limit order's offer is logged as suspicious. Warn only. */
|
|
3694
|
-
private readonly maxOverfillBps;
|
|
3695
|
-
/** Consecutive clamped evaluations before halting. Dormant, as `consecutiveClamps` is. */
|
|
3696
|
-
private readonly maxConsecutiveClamps;
|
|
3697
|
-
confirmationPolicy?: {
|
|
3698
|
-
getConfirmationBlocks: (chainId: number, amountUsd: number) => number;
|
|
3699
|
-
};
|
|
3700
|
-
private fundingVenues;
|
|
3701
|
-
/** The operator's resting orders: the only thing that prices a fill. */
|
|
3702
|
-
private limitOrders?;
|
|
3703
|
-
/**
|
|
3704
|
-
* @param signer Filler's signing account for UserOp signatures.
|
|
3705
|
-
* @param configService Network/config provider for addresses and decimals.
|
|
3706
|
-
* @param clientManager Used to get viem PublicClients for chains.
|
|
3707
|
-
* @param contractService Shared contract interaction service.
|
|
3708
|
-
* @param pairs Trading pairs with their bid/ask price policies and per-order caps.
|
|
3709
|
-
* @param registry Asset symbol registry resolving pair symbols per chain.
|
|
3710
|
-
* @param options.confirmationPolicy Optional per-chain confirmation policy for cross-chain orders.
|
|
3711
|
-
* @param options.fundingVenues Optional funding venues for on-chain liquidity sourcing.
|
|
3712
|
-
*/
|
|
3713
|
-
constructor(signer: Signer, configService: FillerConfigService, clientManager: ChainClientManager, contractService: ContractInteractionService, pairs: TradingPair[], registry: AssetRegistry, options?: {
|
|
3714
|
-
confirmationPolicy?: ConfirmationPolicy;
|
|
3715
|
-
fundingVenues?: FundingVenue[];
|
|
3716
|
-
/** Where prices come from. Without it the engine matches nothing and fills nothing. */
|
|
3717
|
-
limitOrders?: LimitOrderStore;
|
|
3718
|
-
});
|
|
3719
|
-
/** Per-pair invariants, shared by the constructor and addPair. Adds the accepted pair's label to `seenPairs`. */
|
|
3720
|
-
private static assertPairValid;
|
|
3721
|
-
/**
|
|
3722
|
-
* Adds a market to the running engine. All-or-nothing: the pair passes the
|
|
3723
|
-
* same duplicate and reverse-orientation checks the constructor enforces
|
|
3724
|
-
* before it is pushed.
|
|
3725
|
-
*/
|
|
3726
|
-
addPair(pair: TradingPair): void;
|
|
3727
|
-
/**
|
|
3728
|
-
* Removes a market from the running engine. At least one market must remain.
|
|
3729
|
-
* Matching reads the limit orders rather than the pairs, so removing a market
|
|
3730
|
-
* changes what the dashboard lists, not what the filler fills.
|
|
3731
|
-
*/
|
|
3732
|
-
removePair(pair: TradingPair): void;
|
|
3733
|
-
/**
|
|
3734
|
-
* Call once at startup after construction.
|
|
3735
|
-
* Hydrates all funding venue state before any fill sources from it.
|
|
3736
|
-
*/
|
|
3737
|
-
initialise(): Promise<void>;
|
|
3738
|
-
canFill(order: Order): Promise<boolean>;
|
|
3739
|
-
/**
|
|
3740
|
-
* Evaluates whether an order is profitable to fill against the operator's
|
|
3741
|
-
* limit orders and the filler's current token balances.
|
|
3742
|
-
*
|
|
3743
|
-
* High-level flow:
|
|
3744
|
-
* - Match each (input, output) leg against the open limit orders.
|
|
3745
|
-
* - Build one bid per matching order, best offer first, each paying the
|
|
3746
|
-
* order's whole offer for the input at its own rate, capped by what the
|
|
3747
|
-
* order has left. The gateway credits the swapper the ask and splits
|
|
3748
|
-
* anything above it between the swapper and the protocol.
|
|
3749
|
-
* - Treat a payout below the ask as a partial fill, which only orders
|
|
3750
|
-
* without output calldata and without an earlier partial fill allow.
|
|
3751
|
-
* - Cap each payout by the filler's balance plus funding-venue withdrawals,
|
|
3752
|
-
* then gate it on fees (full fills of orders below `minOrderSizeUsd`) and the
|
|
3753
|
-
* same-asset spread.
|
|
3754
|
-
* - Cache the resulting bids for later use in `executeOrder`.
|
|
3755
|
-
*/
|
|
3756
|
-
calculateProfitability(order: Order): Promise<number>;
|
|
3757
|
-
/**
|
|
3758
|
-
* Executes an order by submitting a bid via the IntentsCoprocessor.
|
|
3759
|
-
*
|
|
3760
|
-
* Assumes that `calculateProfitability` has already been called for the
|
|
3761
|
-
* given order so that filler outputs are cached in `contractService`.
|
|
3762
|
-
* This method only orchestrates the bid construction and submission; the
|
|
3763
|
-
* actual token movements are handled on-chain by the IntentGateway.
|
|
3764
|
-
*/
|
|
3765
|
-
executeOrder(order: Order, intentsCoprocessor?: IntentsCoprocessor): Promise<ExecutionResult>;
|
|
3766
|
-
/**
|
|
3767
|
-
* Prepares and submits a bid UserOp to Hyperbridge for the given order.
|
|
3768
|
-
*
|
|
3769
|
-
* Uses the filler outputs previously cached by `calculateProfitability`.
|
|
3770
|
-
* Approval bundling and UserOp construction are handled by
|
|
3771
|
-
* `ContractInteractionService.prepareBidUserOp`.
|
|
3772
|
-
*/
|
|
3773
|
-
private submitBid;
|
|
3774
|
-
/**
|
|
3775
|
-
* Update consecutive-clamp counter after a successful order evaluation.
|
|
3776
|
-
*
|
|
3777
|
-
* Dormant. Only venue-priced legs ever fed a clamped outcome here: a streak
|
|
3778
|
-
* of those meant a live market source had gone off (stale pool, manipulated
|
|
3779
|
-
* venue). Venue pricing went with Uniswap V4, and limit orders are prices the
|
|
3780
|
-
* operator set, so the only caller records `false` and the filler never
|
|
3781
|
-
* halts. `isHalted`, `resetHalt` and `[simplex.overfillProtection]
|
|
3782
|
-
* maxConsecutiveClamps` are kept so existing configs and the halt API still
|
|
3783
|
-
* load; they can go once nothing reads them.
|
|
3784
|
-
*/
|
|
3785
|
-
private recordOrderOutcome;
|
|
3786
|
-
isHalted(): boolean;
|
|
3787
|
-
/** Operator acknowledgement after investigating a self-halt; resumes filling. */
|
|
3788
|
-
resetHalt(): void;
|
|
3789
|
-
/**
|
|
3790
|
-
* Whether any solver has already delivered output against this order.
|
|
3791
|
-
*
|
|
3792
|
-
* Fails closed: a read that errors returns true, so an order we cannot price
|
|
3793
|
-
* confidently is left alone rather than bid on with stale escrow assumptions.
|
|
3794
|
-
*/
|
|
3795
|
-
private hasExistingPartialFill;
|
|
3796
|
-
/**
|
|
3797
|
-
* Reads and caches the filler's balance for a token on the destination chain.
|
|
3798
|
-
*
|
|
3799
|
-
* Normalizes the token address, checks an in-memory cache, and only hits
|
|
3800
|
-
* the chain (native `getBalance` or ERC20 `balanceOf`) on a cache miss.
|
|
3801
|
-
* This allows multiple legs within a single profitability evaluation to
|
|
3802
|
-
* share the same balance pool.
|
|
3803
|
-
*/
|
|
3804
|
-
private getAndCacheBalance;
|
|
3805
|
-
/**
|
|
3806
|
-
* Resolves every (input, output) leg of an order to a configured pair in one
|
|
3807
|
-
* pass. Returns null if any leg matches no pair (or a disabled direction).
|
|
3808
|
-
*
|
|
3809
|
-
* The address-level classification is cached per order id in the shared
|
|
3810
|
-
* cache (as `CachedPairClassification`, one entry per leg) so repeated
|
|
3811
|
-
* evaluations skip re-derivation; pair resolution itself is re-run per
|
|
3812
|
-
* strategy since pair sets differ between engine instances.
|
|
3813
|
-
*/
|
|
3814
|
-
/** Whether any leg of the order matches a limit order: what `canFill` asks. */
|
|
3815
|
-
private matchOrder;
|
|
3816
|
-
/**
|
|
3817
|
-
* The limit orders one leg of an order is priced against, best offer first, or
|
|
3818
|
-
* none when nothing serves it.
|
|
3819
|
-
*
|
|
3820
|
-
* Amounts cross into the matcher at 1e18, the unit limit orders are kept in,
|
|
3821
|
-
* and the payout comes back in the same unit for the caller to bring down to
|
|
3822
|
-
* the output token's own decimals.
|
|
3823
|
-
*/
|
|
3824
|
-
private matchLeg;
|
|
3825
|
-
/** Why no limit order serves the order, leg by leg, for the line that says it was passed over. */
|
|
3826
|
-
private explainUnmatched;
|
|
3827
|
-
/**
|
|
3828
|
-
* One leg as the matcher sees it, or null when its input token is not one the asset
|
|
3829
|
-
* registry knows on the source chain.
|
|
3830
|
-
*
|
|
3831
|
-
* Amounts cross into the matcher at 1e18, the unit limit orders are kept in.
|
|
3832
|
-
*/
|
|
3833
|
-
private incomingFor;
|
|
3834
|
-
/**
|
|
3835
|
-
* The order's input in **USD**, or null when no limit order connects its input
|
|
3836
|
-
* token to a dollar.
|
|
3837
|
-
*
|
|
3838
|
-
* The core filler feeds this to the per-chain confirmation curves, whose
|
|
3839
|
-
* amount axis is dollars. Null is the honest answer when the route is missing:
|
|
3840
|
-
* the caller waits on this figure, and inventing one would under-wait a large
|
|
3841
|
-
* order against a source chain that has not finalised.
|
|
3842
|
-
*/
|
|
3843
|
-
getOrderUsdValue(order: Order): Promise<{
|
|
3844
|
-
inputUsd: Decimal;
|
|
3845
|
-
} | null>;
|
|
3846
|
-
}
|
|
3847
|
-
|
|
3848
|
-
interface SendTokenParams {
|
|
3849
|
-
/** State machine id, e.g. "EVM-8453". */
|
|
3850
|
-
chain: string;
|
|
3851
|
-
/** "native" or an ERC-20 address. Configured vault shares are redeemed to the recipient instead of transferred. */
|
|
3852
|
-
token: string;
|
|
3853
|
-
/** Human-readable amount, parsed against the token's decimals. */
|
|
3854
|
-
amount: string;
|
|
3855
|
-
to: HexString;
|
|
3856
|
-
}
|
|
3857
|
-
interface SendTokenResult {
|
|
3858
|
-
txHash: HexString;
|
|
3859
|
-
sponsored: boolean;
|
|
3860
|
-
/** Set when vault holdings were redeemed as part of the send. */
|
|
3861
|
-
redeemed: boolean;
|
|
3862
|
-
}
|
|
3863
|
-
/**
|
|
3864
|
-
* Operator-initiated outbound transfers from the filler wallet. Uses the same
|
|
3865
|
-
* sponsored UserOp path as fills (gas paid by the paymaster) with a native-tx
|
|
3866
|
-
* fallback. When the wallet balance of an ERC-20 falls short and a configured
|
|
3867
|
-
* ERC-4626 vault holds it as underlying, the shortfall is withdrawn from the
|
|
3868
|
-
* vault in the same batch as the transfer. Sending a vault's share token
|
|
3869
|
-
* directly issues `redeem(shares, recipient, solver)` — shares only ever
|
|
3870
|
-
* leave as the underlying asset.
|
|
3871
|
-
*/
|
|
3872
|
-
declare class TokenSender {
|
|
3873
|
-
private readonly clientManager;
|
|
3874
|
-
private readonly solver;
|
|
3875
|
-
/** Live view of the configured vaults so runtime vault edits are honored. */
|
|
3876
|
-
private readonly getVaults;
|
|
3877
|
-
private readonly userOpSender?;
|
|
3878
|
-
/** Only needed to size the paymaster's gas reserve; without it a send reserves nothing. */
|
|
3879
|
-
private readonly configService?;
|
|
3880
|
-
private readonly logger;
|
|
3881
|
-
constructor(clientManager: ChainClientManager, solver: HexString,
|
|
3882
|
-
/** Live view of the configured vaults so runtime vault edits are honored. */
|
|
3883
|
-
getVaults: () => VaultToml[], userOpSender?: UserOpSender | undefined,
|
|
3884
|
-
/** Only needed to size the paymaster's gas reserve; without it a send reserves nothing. */
|
|
3885
|
-
configService?: FillerConfigService | undefined);
|
|
3886
|
-
send(params: SendTokenParams): Promise<SendTokenResult>;
|
|
3887
|
-
/**
|
|
3888
|
-
* A `withdraw(shortfall, solver, solver)` call against a configured vault on
|
|
3889
|
-
* this chain whose underlying is the token being sent and that can cover the
|
|
3890
|
-
* shortfall, or null when no vault can.
|
|
3891
|
-
*/
|
|
3892
|
-
/**
|
|
3893
|
-
* A withdrawal that funds the transfer and, where the vault can afford it,
|
|
3894
|
-
* leaves headroom in the wallet rather than nothing.
|
|
3895
|
-
*
|
|
3896
|
-
* `shortfall` is what the transfer cannot do without, and is zero or negative
|
|
3897
|
-
* when the wallet already covers it. The headroom is the larger of the
|
|
3898
|
-
* paymaster's gas `reserve` and the vault's `minBalance` — the first is what
|
|
3899
|
-
* validation will pull out of this wallet, the second is the operator's own
|
|
3900
|
-
* statement of the working balance this token keeps. A vault that can only
|
|
3901
|
-
* cover the shortfall still funds the send: headroom is a preference, not a
|
|
3902
|
-
* reason to refuse a transfer the operator asked for.
|
|
3903
|
-
*/
|
|
3904
|
-
private vaultWithdrawalCall;
|
|
3905
|
-
private submit;
|
|
3906
|
-
}
|
|
3907
|
-
|
|
3908
2360
|
/** Everything a running filler exposes to the UI server and the CLI. */
|
|
3909
2361
|
interface FillerRuntime {
|
|
3910
2362
|
intentFiller: IntentFiller;
|
|
3911
2363
|
balanceProvider: BalanceProvider;
|
|
3912
2364
|
vaultVenue?: VaultFundingPlanner;
|
|
3913
|
-
/** The markets this filler serves, for the operator UI. */
|
|
3914
|
-
adminStrategies: AdminStrategy[];
|
|
3915
2365
|
/** Self-halt visibility/reset for the trading engine (overfill protection). */
|
|
3916
2366
|
haltControls: HaltControl[];
|
|
3917
2367
|
/** Live order-activity bridge; emits `event` per stored row. */
|
|
@@ -3944,12 +2394,6 @@ interface FillerRuntime {
|
|
|
3944
2394
|
assetRegistry: AssetRegistry;
|
|
3945
2395
|
/** Creates and posts the operator's limit orders. */
|
|
3946
2396
|
limitOrders?: LimitOrderService;
|
|
3947
|
-
/** The live trading engine. It runs whether or not the config names any pairs. */
|
|
3948
|
-
engine: FXFiller;
|
|
3949
|
-
/** The engine's live pair array (same instance), indexed 1:1 with config.pairs. */
|
|
3950
|
-
tradingPairs: TradingPair[];
|
|
3951
|
-
/** BalanceProvider's live token1 map (chain name to exotic addresses); mutations apply on its next refresh. */
|
|
3952
|
-
balanceTokens: Record<string, string[]>;
|
|
3953
2397
|
rebalancingService?: RebalancingService;
|
|
3954
2398
|
resolvedChains: ResolvedChainConfig[];
|
|
3955
2399
|
fillerAddress: HexString;
|
|
@@ -3969,6 +2413,8 @@ interface FillerRuntime {
|
|
|
3969
2413
|
vaultPreflight(vaults: VaultToml[]): Promise<void>;
|
|
3970
2414
|
/** Operator-initiated outbound transfers (dashboard Send). */
|
|
3971
2415
|
tokenSender: TokenSender;
|
|
2416
|
+
/** Buys BRIDGE on BSC for the filler's Hyperbridge account. Absent without a substrate key. */
|
|
2417
|
+
bridgeTopUp?: BridgeTopUp;
|
|
3972
2418
|
startedAt: number;
|
|
3973
2419
|
/** Stops everything bootFiller started. Idempotent; does NOT process.exit. */
|
|
3974
2420
|
shutdown(signal: string): Promise<void>;
|
|
@@ -4118,23 +2564,16 @@ interface SimplexEvents {
|
|
|
4118
2564
|
order: LimitOrder;
|
|
4119
2565
|
};
|
|
4120
2566
|
}
|
|
4121
|
-
interface PairView {
|
|
4122
|
-
index: number;
|
|
4123
|
-
token0: string;
|
|
4124
|
-
token1: string;
|
|
4125
|
-
/** token0 === token1: the same-asset cross-chain market. */
|
|
4126
|
-
sameToken: boolean;
|
|
4127
|
-
}
|
|
4128
2567
|
interface ChainView {
|
|
4129
2568
|
chainId: number;
|
|
4130
2569
|
stateMachineId: string;
|
|
4131
2570
|
rpcUrls: string[];
|
|
2571
|
+
/** Hyperbridge's bundler the chain fills through, empty where it runs none. */
|
|
4132
2572
|
bundlerUrl: string;
|
|
4133
2573
|
watchOnly: boolean;
|
|
4134
2574
|
}
|
|
4135
2575
|
interface ChainInput {
|
|
4136
2576
|
rpcUrls: string[];
|
|
4137
|
-
bundlerUrl: string;
|
|
4138
2577
|
watchOnly?: boolean;
|
|
4139
2578
|
/**
|
|
4140
2579
|
* Required for chains with no built-in confirmation curve (testnets and
|
|
@@ -4152,9 +2591,7 @@ interface SimplexStatus {
|
|
|
4152
2591
|
uptimeSec: number;
|
|
4153
2592
|
chains: number[];
|
|
4154
2593
|
watchOnly: Record<number, boolean>;
|
|
4155
|
-
pairs: number;
|
|
4156
2594
|
}
|
|
4157
|
-
/** Trading pairs of the running engine. Every mutation binds on the next order. */
|
|
4158
2595
|
/**
|
|
4159
2596
|
* The operator's limit orders: what simplex offers to pay, and what the
|
|
4160
2597
|
* orderbook advertises on its behalf.
|
|
@@ -4198,7 +2635,7 @@ declare class LimitOrderController {
|
|
|
4198
2635
|
profitability(period: ProfitPeriod, tzOffsetMinutes?: number): Promise<Profitability>;
|
|
4199
2636
|
/** One reader for the life of the filler, so the readings it has already fetched are kept. */
|
|
4200
2637
|
private indexerInventory;
|
|
4201
|
-
/** The
|
|
2638
|
+
/** The books the orderbook lists, the smallest payout each token may carry, and its tokens per chain. */
|
|
4202
2639
|
books(): Promise<{
|
|
4203
2640
|
books: Book[];
|
|
4204
2641
|
minOrderSizes: TokenMinSize[];
|
|
@@ -4214,26 +2651,6 @@ declare class LimitOrderController {
|
|
|
4214
2651
|
}
|
|
4215
2652
|
/** How the controller publishes an outcome on the `Simplex` it belongs to. */
|
|
4216
2653
|
type LimitOrderEmitter = <E extends "limit-order:posted" | "limit-order:rejected" | "limit-order:cancelled" | "limit-order:resized" | "limit-order:filled">(event: E, payload: SimplexEvents[E]) => void;
|
|
4217
|
-
declare class PairController {
|
|
4218
|
-
private runtime;
|
|
4219
|
-
private persist;
|
|
4220
|
-
constructor(runtime: FillerRuntime, persist: () => void | Promise<void>);
|
|
4221
|
-
private get pairs();
|
|
4222
|
-
list(): PairView[];
|
|
4223
|
-
/**
|
|
4224
|
-
* Opens a new market on the running engine.
|
|
4225
|
-
*
|
|
4226
|
-
* Validated against the same rules boot applies, so a pair accepted here is
|
|
4227
|
-
* one a restart would also accept. New `assets` are registered first, because
|
|
4228
|
-
* the pair's symbols have to resolve before the market can be hydrated.
|
|
4229
|
-
*/
|
|
4230
|
-
add(pair: PairConfig, options?: {
|
|
4231
|
-
assets?: Record<string, AssetDefinition>;
|
|
4232
|
-
}): Promise<PairView>;
|
|
4233
|
-
/** Closes a market. Orders already in flight against it still complete. */
|
|
4234
|
-
remove(index: number): Promise<void>;
|
|
4235
|
-
private livePair;
|
|
4236
|
-
}
|
|
4237
2654
|
/** The chain set of the running filler. */
|
|
4238
2655
|
declare class ChainController {
|
|
4239
2656
|
private runtime;
|
|
@@ -4282,7 +2699,6 @@ declare class ChainController {
|
|
|
4282
2699
|
* leaves no gap in the scanned block range.
|
|
4283
2700
|
*/
|
|
4284
2701
|
setRpcUrls(chainId: number, rpcUrls: string[]): Promise<void>;
|
|
4285
|
-
setBundlerUrl(chainId: number, bundlerUrl: string): Promise<void>;
|
|
4286
2702
|
/** Monitor without filling. Takes effect on the next order. */
|
|
4287
2703
|
setWatchOnly(chainId: number, watchOnly: boolean): Promise<void>;
|
|
4288
2704
|
/** A global boolean is left alone — expanding it per chain changes how the config validates. */
|
|
@@ -4358,7 +2774,7 @@ declare class RebalanceController {
|
|
|
4358
2774
|
*
|
|
4359
2775
|
* Start one with {@link Simplex.start}, which boots every service, delegates the
|
|
4360
2776
|
* filler account where solver selection is active, and begins scanning the
|
|
4361
|
-
* configured chains. The instance is the whole control surface:
|
|
2777
|
+
* configured chains. The instance is the whole control surface: limit orders,
|
|
4362
2778
|
* chains, vaults, assets, wallet and rebalancing are reachable as controllers,
|
|
4363
2779
|
* and everything the filler does is observable through {@link SimplexEvents}.
|
|
4364
2780
|
*
|
|
@@ -4369,12 +2785,11 @@ declare class RebalanceController {
|
|
|
4369
2785
|
*
|
|
4370
2786
|
* More than one instance can run in one process. They share no state.
|
|
4371
2787
|
*/
|
|
4372
|
-
declare class Simplex extends EventEmitter
|
|
2788
|
+
declare class Simplex extends EventEmitter {
|
|
4373
2789
|
private runtime;
|
|
4374
2790
|
private options;
|
|
4375
2791
|
/** The scanner this filler built for itself, and must therefore close. */
|
|
4376
2792
|
private ownedScanners;
|
|
4377
|
-
readonly pairs: PairController;
|
|
4378
2793
|
readonly chains: ChainController;
|
|
4379
2794
|
readonly vaults: VaultController;
|
|
4380
2795
|
readonly assets: AssetController;
|
|
@@ -4521,4 +2936,4 @@ declare class OrderScanner implements OrderScanner$1 {
|
|
|
4521
2936
|
private closeNow;
|
|
4522
2937
|
}
|
|
4523
2938
|
|
|
4524
|
-
export { ActivityEvent, ActivityInsert, ActivityStore,
|
|
2939
|
+
export { ActivityEvent, ActivityInsert, ActivityStore, AllowlistConfig, type AssetBalanceRow, AssetController, AssetDefinition, type BalanceIssue, type BalanceSnapshot, BidStats, BidStore, type BookProfit, type CancelledLimitOrder, type ChainBalanceRow, ChainConfirmationPolicy, ChainController, type ChainInput, type ChainView, type CreateLimitOrderRequest, DerivingSigner, FillerTomlConfig, type HyperbridgeBalance, InventoryStore, LimitOrder, LimitOrderController, LimitOrderFill, LimitOrderFilter, LimitOrderStore, LimitOrderValidationError, LogLevel, LogSink, LoggerContext, MemoryDataStore, MpcVaultSignerConfig, OrderScanner, type OrderScanner$1 as OrderScannerContract, type OrderScannerHandlers, type OrderScannerOptions, type PostedLimitOrder, type PostingOutcome, type ProfitBucket, type ProfitBucketFigures, type ProfitFigures, type ProfitPeriod, type Profitability, RebalanceController, RebalancingConfig, ResolvedChainConfig, type ScannedFill, type ScannedOrder, type ScannerChainConfig, SecretPhraseSignerConfig, Signature, Signer, SignerConfig, Simplex, type SimplexConfig, SimplexDataStore, type SimplexEvents, type SimplexOptions, type SimplexStatus, type SolverWork, type StartingInventory, StateStore, StoredBid, type Subscription, TurnkeySignerConfig, type VaultBalanceRow, VaultController, type VaultSweepDeposit, type VaultSweepResult, type VaultSweepSkip, type VaultSweepSkipReason, type VaultSweepSubmission, VaultToml, WalletController, WalletTx, canDerive, createSigner, digestSigner, mpcVaultSigner, privateKeySigner, secretPhraseSigner, turnkeySigner, validateSecretPhrase, validateSignerConfig, viemSigner };
|