@hyperbridge/simplex 0.16.5 → 0.16.6
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/dist/bin/simplex.js +72 -8
- package/dist/bin/simplex.js.map +1 -1
- package/dist/index.cjs +67 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -3
- package/dist/index.d.ts +45 -3
- package/dist/index.js +67 -8
- package/dist/index.js.map +1 -1
- package/dist/ui/assets/index-CsBo6xg3.js +106 -0
- package/dist/ui/assets/{index-DwJCXJ6a.css → index-PIGVK8XG.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/index-Bv9S1oj4.js +0 -106
package/dist/bin/simplex.js
CHANGED
|
@@ -318650,10 +318650,16 @@ var CANCEL_ORDER_MUTATION = `
|
|
|
318650
318650
|
`;
|
|
318651
318651
|
var OrderbookRequestError2 = class extends Error {
|
|
318652
318652
|
};
|
|
318653
|
+
function graphqlEndpoint(url2) {
|
|
318654
|
+
const trimmed = url2.trim();
|
|
318655
|
+
if (trimmed.includes("?")) return trimmed;
|
|
318656
|
+
const withoutTrailingSlash = trimmed.replace(/\/+$/, "");
|
|
318657
|
+
return withoutTrailingSlash.endsWith("/graphql") ? withoutTrailingSlash : `${withoutTrailingSlash}/graphql`;
|
|
318658
|
+
}
|
|
318653
318659
|
var OrderbookClient = class {
|
|
318654
318660
|
constructor(url2, requestTimeoutMs, loggers = defaultLoggerContext()) {
|
|
318655
|
-
this.url = url2;
|
|
318656
318661
|
this.requestTimeoutMs = requestTimeoutMs;
|
|
318662
|
+
this.url = graphqlEndpoint(url2);
|
|
318657
318663
|
this.logger = loggers.get("orderbook");
|
|
318658
318664
|
}
|
|
318659
318665
|
/** The limits to validate against before posting, plus the books on offer. */
|
|
@@ -318751,7 +318757,9 @@ var OrderbookClient = class {
|
|
|
318751
318757
|
clearTimeout(timer);
|
|
318752
318758
|
}
|
|
318753
318759
|
if (!response.ok) {
|
|
318754
|
-
throw new OrderbookRequestError2(
|
|
318760
|
+
throw new OrderbookRequestError2(
|
|
318761
|
+
`Orderbook at ${this.url} returned HTTP ${response.status} ${response.statusText}`
|
|
318762
|
+
);
|
|
318755
318763
|
}
|
|
318756
318764
|
const body = await response.json().catch((err) => {
|
|
318757
318765
|
throw new OrderbookRequestError2(`Orderbook returned a body that is not JSON: ${describe(err)}`);
|
|
@@ -318870,7 +318878,7 @@ var HEARTBEAT_TYPES = {
|
|
|
318870
318878
|
var LimitOrderValidationError = class extends Error {
|
|
318871
318879
|
};
|
|
318872
318880
|
var LimitOrderService = class {
|
|
318873
|
-
constructor(store, client, contractService, configService, assetRegistry, signer, defaultTtlSecs, delegationService, loggers = defaultLoggerContext(), startingNonce = initialOrderNonce) {
|
|
318881
|
+
constructor(store, client, contractService, configService, assetRegistry, signer, defaultTtlSecs, delegationService, loggers = defaultLoggerContext(), startingNonce = initialOrderNonce, vaultBalances) {
|
|
318874
318882
|
this.store = store;
|
|
318875
318883
|
this.client = client;
|
|
318876
318884
|
this.contractService = contractService;
|
|
@@ -318880,6 +318888,7 @@ var LimitOrderService = class {
|
|
|
318880
318888
|
this.defaultTtlSecs = defaultTtlSecs;
|
|
318881
318889
|
this.delegationService = delegationService;
|
|
318882
318890
|
this.startingNonce = startingNonce;
|
|
318891
|
+
this.vaultBalances = vaultBalances;
|
|
318883
318892
|
this.logger = loggers.get("limit-orders");
|
|
318884
318893
|
}
|
|
318885
318894
|
/**
|
|
@@ -319015,6 +319024,16 @@ var LimitOrderService = class {
|
|
|
319015
319024
|
throw err;
|
|
319016
319025
|
}
|
|
319017
319026
|
}
|
|
319027
|
+
/**
|
|
319028
|
+
* The pairs an order can be written against, and the smallest payout each token may carry.
|
|
319029
|
+
*
|
|
319030
|
+
* The orderbook lists the books; `resolveBook` refuses a request naming anything else, so the
|
|
319031
|
+
* operator is offered exactly these and no combination of symbols they could not post.
|
|
319032
|
+
*/
|
|
319033
|
+
async books() {
|
|
319034
|
+
const limits = await this.limits();
|
|
319035
|
+
return { books: limits.books, minOrderSizes: limits.serverInfo.minOrderSizes };
|
|
319036
|
+
}
|
|
319018
319037
|
/**
|
|
319019
319038
|
* Reads `serverInfo` and `books`, reusing the last read for {@link LIMITS_TTL_MS}.
|
|
319020
319039
|
*
|
|
@@ -319122,28 +319141,61 @@ var LimitOrderService = class {
|
|
|
319122
319141
|
* balance on the fill chain, so the operator hears it while they are creating
|
|
319123
319142
|
* the order.
|
|
319124
319143
|
*
|
|
319144
|
+
* A fill pays out of the wallet and then withdraws any shortfall from the
|
|
319145
|
+
* configured ERC-4626 vaults in the same batch, so what those vaults hold of
|
|
319146
|
+
* the payout token backs the order too and is counted here. Without it an
|
|
319147
|
+
* operator who sweeps inventory into a vault is refused orders their filler
|
|
319148
|
+
* would have filled.
|
|
319149
|
+
*
|
|
319125
319150
|
* Each order is checked against the whole balance, not against what is left of
|
|
319126
319151
|
* it after the others. One balance backs every order resting on it — that is
|
|
319127
319152
|
* what quoting both sides of a book is — and the orderbook says as much: it
|
|
319128
319153
|
* advertises each entry at `min(quoted, balance)` rather than dividing the
|
|
319129
319154
|
* balance between them. Whichever order fills first draws the inventory down,
|
|
319130
319155
|
* and the rest are cut to what is left. Netting them here would refuse the
|
|
319131
|
-
* second side of every book.
|
|
319156
|
+
* second side of every book. Vault positions are counted the same way: the
|
|
319157
|
+
* whole position, not what is left after reservations for fills in flight.
|
|
319132
319158
|
*/
|
|
319133
319159
|
async assertWalletCanPay(symbol3, chain2, payout) {
|
|
319134
319160
|
const token = this.assetRegistry.getAddress(symbol3, chain2);
|
|
319135
319161
|
if (!token) return;
|
|
319136
319162
|
const decimals = await this.decimalsFor(symbol3, token, chain2);
|
|
319137
|
-
const
|
|
319163
|
+
const wallet = toScaled(
|
|
319138
319164
|
await this.contractService.getTokenBalance(chain2, token, this.signer.address),
|
|
319139
319165
|
decimals
|
|
319140
319166
|
);
|
|
319141
|
-
|
|
319167
|
+
const vaults = await this.vaultHoldings(token, chain2);
|
|
319168
|
+
if (wallet + vaults < payout) {
|
|
319169
|
+
const held = vaults > 0n ? `${toHuman(wallet)} in the wallet and ${toHuman(vaults)} in vaults` : toHuman(wallet);
|
|
319142
319170
|
throw new LimitOrderValidationError(
|
|
319143
|
-
`The wallet holds ${
|
|
319171
|
+
`The wallet holds ${held} ${symbol3} on ${chain2}, which cannot pay out ${toHuman(payout)}`
|
|
319144
319172
|
);
|
|
319145
319173
|
}
|
|
319146
319174
|
}
|
|
319175
|
+
/**
|
|
319176
|
+
* What the configured vaults hold of `token` on `chain`, in scaled units.
|
|
319177
|
+
*
|
|
319178
|
+
* Zero when no vault is configured. A snapshot that cannot be read is also
|
|
319179
|
+
* zero: the wallet alone then has to cover the order, which refuses one the
|
|
319180
|
+
* filler might have managed rather than accepting one it could not.
|
|
319181
|
+
*/
|
|
319182
|
+
async vaultHoldings(token, chain2) {
|
|
319183
|
+
if (!this.vaultBalances) return 0n;
|
|
319184
|
+
let positions;
|
|
319185
|
+
try {
|
|
319186
|
+
positions = await this.vaultBalances.getBalanceSnapshot(chain2);
|
|
319187
|
+
} catch (err) {
|
|
319188
|
+
this.logger.warn({ chain: chain2, token, err }, "Could not read vault balances; backing the order on the wallet alone");
|
|
319189
|
+
return 0n;
|
|
319190
|
+
}
|
|
319191
|
+
const wanted = token.toLowerCase();
|
|
319192
|
+
let total = 0n;
|
|
319193
|
+
for (const position of positions) {
|
|
319194
|
+
if (position.chain !== chain2 || position.asset.toLowerCase() !== wanted) continue;
|
|
319195
|
+
total += toScaled(position.positionAssets, position.decimals);
|
|
319196
|
+
}
|
|
319197
|
+
return total;
|
|
319198
|
+
}
|
|
319147
319199
|
/**
|
|
319148
319200
|
* Works a limit order down by what a fill delivered, and puts the rest back on
|
|
319149
319201
|
* the orderbook.
|
|
@@ -321732,6 +321784,11 @@ var UiServer = class {
|
|
|
321732
321784
|
if (method === "POST") return this.handleLimitOrderCreate(req, res);
|
|
321733
321785
|
return sendJson(res, 405, { error: "Method not allowed" });
|
|
321734
321786
|
}
|
|
321787
|
+
if (path2 === "/api/orderbook/books") {
|
|
321788
|
+
if (this.mode !== "operator") return sendJson(res, 409, { error: "Filler is not running" });
|
|
321789
|
+
if (method !== "GET") return sendJson(res, 405, { error: "Method not allowed" });
|
|
321790
|
+
return this.handleLimitOrders(res, () => this.operator.limitOrders.books());
|
|
321791
|
+
}
|
|
321735
321792
|
const limitOrderMatch = path2.match(/^\/api\/limit-orders\/([\w-]+)$/);
|
|
321736
321793
|
if (limitOrderMatch) {
|
|
321737
321794
|
if (this.mode !== "operator") return sendJson(res, 409, { error: "Filler is not running" });
|
|
@@ -364615,7 +364672,10 @@ async function bootFiller(config5, options) {
|
|
|
364615
364672
|
runtimeSigner,
|
|
364616
364673
|
config5.orderbook.defaultTtlSecs ?? DEFAULT_LIMIT_ORDER_TTL_SECONDS,
|
|
364617
364674
|
new DelegationService(chainClientManager, configService, runtimeSigner),
|
|
364618
|
-
options.loggers
|
|
364675
|
+
options.loggers,
|
|
364676
|
+
initialOrderNonce,
|
|
364677
|
+
// A fill withdraws a payout shortfall from the vaults, so what they hold backs an order too.
|
|
364678
|
+
vaultVenue
|
|
364619
364679
|
);
|
|
364620
364680
|
intentFiller.setLimitOrderService(limitOrderService);
|
|
364621
364681
|
const lifecycle = new LimitOrderLifecycle(
|
|
@@ -365702,6 +365762,10 @@ var LimitOrderController = class {
|
|
|
365702
365762
|
]);
|
|
365703
365763
|
return { order, fills, bids };
|
|
365704
365764
|
}
|
|
365765
|
+
/** The pairs the orderbook lists, and the smallest payout each token may carry. */
|
|
365766
|
+
books() {
|
|
365767
|
+
return this.service.books();
|
|
365768
|
+
}
|
|
365705
365769
|
/** Creates the order, posts it, and reports what the orderbook made of it. */
|
|
365706
365770
|
async create(request3) {
|
|
365707
365771
|
const posted = await this.service.create(request3);
|