@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/index.cjs
CHANGED
|
@@ -2654,10 +2654,16 @@ var CANCEL_ORDER_MUTATION = `
|
|
|
2654
2654
|
`;
|
|
2655
2655
|
var OrderbookRequestError = class extends Error {
|
|
2656
2656
|
};
|
|
2657
|
+
function graphqlEndpoint(url) {
|
|
2658
|
+
const trimmed = url.trim();
|
|
2659
|
+
if (trimmed.includes("?")) return trimmed;
|
|
2660
|
+
const withoutTrailingSlash = trimmed.replace(/\/+$/, "");
|
|
2661
|
+
return withoutTrailingSlash.endsWith("/graphql") ? withoutTrailingSlash : `${withoutTrailingSlash}/graphql`;
|
|
2662
|
+
}
|
|
2657
2663
|
var OrderbookClient = class {
|
|
2658
2664
|
constructor(url, requestTimeoutMs, loggers = defaultLoggerContext()) {
|
|
2659
|
-
this.url = url;
|
|
2660
2665
|
this.requestTimeoutMs = requestTimeoutMs;
|
|
2666
|
+
this.url = graphqlEndpoint(url);
|
|
2661
2667
|
this.logger = loggers.get("orderbook");
|
|
2662
2668
|
}
|
|
2663
2669
|
/** The limits to validate against before posting, plus the books on offer. */
|
|
@@ -2755,7 +2761,9 @@ var OrderbookClient = class {
|
|
|
2755
2761
|
clearTimeout(timer);
|
|
2756
2762
|
}
|
|
2757
2763
|
if (!response.ok) {
|
|
2758
|
-
throw new OrderbookRequestError(
|
|
2764
|
+
throw new OrderbookRequestError(
|
|
2765
|
+
`Orderbook at ${this.url} returned HTTP ${response.status} ${response.statusText}`
|
|
2766
|
+
);
|
|
2759
2767
|
}
|
|
2760
2768
|
const body = await response.json().catch((err) => {
|
|
2761
2769
|
throw new OrderbookRequestError(`Orderbook returned a body that is not JSON: ${describe(err)}`);
|
|
@@ -2870,7 +2878,7 @@ var HEARTBEAT_TYPES = {
|
|
|
2870
2878
|
var LimitOrderValidationError = class extends Error {
|
|
2871
2879
|
};
|
|
2872
2880
|
var LimitOrderService = class {
|
|
2873
|
-
constructor(store, client, contractService, configService, assetRegistry, signer, defaultTtlSecs, delegationService, loggers = defaultLoggerContext(), startingNonce = initialOrderNonce) {
|
|
2881
|
+
constructor(store, client, contractService, configService, assetRegistry, signer, defaultTtlSecs, delegationService, loggers = defaultLoggerContext(), startingNonce = initialOrderNonce, vaultBalances) {
|
|
2874
2882
|
this.store = store;
|
|
2875
2883
|
this.client = client;
|
|
2876
2884
|
this.contractService = contractService;
|
|
@@ -2880,6 +2888,7 @@ var LimitOrderService = class {
|
|
|
2880
2888
|
this.defaultTtlSecs = defaultTtlSecs;
|
|
2881
2889
|
this.delegationService = delegationService;
|
|
2882
2890
|
this.startingNonce = startingNonce;
|
|
2891
|
+
this.vaultBalances = vaultBalances;
|
|
2883
2892
|
this.logger = loggers.get("limit-orders");
|
|
2884
2893
|
}
|
|
2885
2894
|
/**
|
|
@@ -3015,6 +3024,16 @@ var LimitOrderService = class {
|
|
|
3015
3024
|
throw err;
|
|
3016
3025
|
}
|
|
3017
3026
|
}
|
|
3027
|
+
/**
|
|
3028
|
+
* The pairs an order can be written against, and the smallest payout each token may carry.
|
|
3029
|
+
*
|
|
3030
|
+
* The orderbook lists the books; `resolveBook` refuses a request naming anything else, so the
|
|
3031
|
+
* operator is offered exactly these and no combination of symbols they could not post.
|
|
3032
|
+
*/
|
|
3033
|
+
async books() {
|
|
3034
|
+
const limits = await this.limits();
|
|
3035
|
+
return { books: limits.books, minOrderSizes: limits.serverInfo.minOrderSizes };
|
|
3036
|
+
}
|
|
3018
3037
|
/**
|
|
3019
3038
|
* Reads `serverInfo` and `books`, reusing the last read for {@link LIMITS_TTL_MS}.
|
|
3020
3039
|
*
|
|
@@ -3122,28 +3141,61 @@ var LimitOrderService = class {
|
|
|
3122
3141
|
* balance on the fill chain, so the operator hears it while they are creating
|
|
3123
3142
|
* the order.
|
|
3124
3143
|
*
|
|
3144
|
+
* A fill pays out of the wallet and then withdraws any shortfall from the
|
|
3145
|
+
* configured ERC-4626 vaults in the same batch, so what those vaults hold of
|
|
3146
|
+
* the payout token backs the order too and is counted here. Without it an
|
|
3147
|
+
* operator who sweeps inventory into a vault is refused orders their filler
|
|
3148
|
+
* would have filled.
|
|
3149
|
+
*
|
|
3125
3150
|
* Each order is checked against the whole balance, not against what is left of
|
|
3126
3151
|
* it after the others. One balance backs every order resting on it — that is
|
|
3127
3152
|
* what quoting both sides of a book is — and the orderbook says as much: it
|
|
3128
3153
|
* advertises each entry at `min(quoted, balance)` rather than dividing the
|
|
3129
3154
|
* balance between them. Whichever order fills first draws the inventory down,
|
|
3130
3155
|
* and the rest are cut to what is left. Netting them here would refuse the
|
|
3131
|
-
* second side of every book.
|
|
3156
|
+
* second side of every book. Vault positions are counted the same way: the
|
|
3157
|
+
* whole position, not what is left after reservations for fills in flight.
|
|
3132
3158
|
*/
|
|
3133
3159
|
async assertWalletCanPay(symbol, chain, payout) {
|
|
3134
3160
|
const token = this.assetRegistry.getAddress(symbol, chain);
|
|
3135
3161
|
if (!token) return;
|
|
3136
3162
|
const decimals = await this.decimalsFor(symbol, token, chain);
|
|
3137
|
-
const
|
|
3163
|
+
const wallet = toScaled(
|
|
3138
3164
|
await this.contractService.getTokenBalance(chain, token, this.signer.address),
|
|
3139
3165
|
decimals
|
|
3140
3166
|
);
|
|
3141
|
-
|
|
3167
|
+
const vaults = await this.vaultHoldings(token, chain);
|
|
3168
|
+
if (wallet + vaults < payout) {
|
|
3169
|
+
const held = vaults > 0n ? `${toHuman(wallet)} in the wallet and ${toHuman(vaults)} in vaults` : toHuman(wallet);
|
|
3142
3170
|
throw new LimitOrderValidationError(
|
|
3143
|
-
`The wallet holds ${
|
|
3171
|
+
`The wallet holds ${held} ${symbol} on ${chain}, which cannot pay out ${toHuman(payout)}`
|
|
3144
3172
|
);
|
|
3145
3173
|
}
|
|
3146
3174
|
}
|
|
3175
|
+
/**
|
|
3176
|
+
* What the configured vaults hold of `token` on `chain`, in scaled units.
|
|
3177
|
+
*
|
|
3178
|
+
* Zero when no vault is configured. A snapshot that cannot be read is also
|
|
3179
|
+
* zero: the wallet alone then has to cover the order, which refuses one the
|
|
3180
|
+
* filler might have managed rather than accepting one it could not.
|
|
3181
|
+
*/
|
|
3182
|
+
async vaultHoldings(token, chain) {
|
|
3183
|
+
if (!this.vaultBalances) return 0n;
|
|
3184
|
+
let positions;
|
|
3185
|
+
try {
|
|
3186
|
+
positions = await this.vaultBalances.getBalanceSnapshot(chain);
|
|
3187
|
+
} catch (err) {
|
|
3188
|
+
this.logger.warn({ chain, token, err }, "Could not read vault balances; backing the order on the wallet alone");
|
|
3189
|
+
return 0n;
|
|
3190
|
+
}
|
|
3191
|
+
const wanted = token.toLowerCase();
|
|
3192
|
+
let total = 0n;
|
|
3193
|
+
for (const position of positions) {
|
|
3194
|
+
if (position.chain !== chain || position.asset.toLowerCase() !== wanted) continue;
|
|
3195
|
+
total += toScaled(position.positionAssets, position.decimals);
|
|
3196
|
+
}
|
|
3197
|
+
return total;
|
|
3198
|
+
}
|
|
3147
3199
|
/**
|
|
3148
3200
|
* Works a limit order down by what a fill delivered, and puts the rest back on
|
|
3149
3201
|
* the orderbook.
|
|
@@ -23559,7 +23611,10 @@ async function bootFiller(config, options) {
|
|
|
23559
23611
|
runtimeSigner,
|
|
23560
23612
|
config.orderbook.defaultTtlSecs ?? DEFAULT_LIMIT_ORDER_TTL_SECONDS,
|
|
23561
23613
|
new DelegationService(chainClientManager, configService, runtimeSigner),
|
|
23562
|
-
options.loggers
|
|
23614
|
+
options.loggers,
|
|
23615
|
+
initialOrderNonce,
|
|
23616
|
+
// A fill withdraws a payout shortfall from the vaults, so what they hold backs an order too.
|
|
23617
|
+
vaultVenue
|
|
23563
23618
|
);
|
|
23564
23619
|
intentFiller.setLimitOrderService(limitOrderService);
|
|
23565
23620
|
const lifecycle = new LimitOrderLifecycle(
|
|
@@ -24630,6 +24685,10 @@ var LimitOrderController = class {
|
|
|
24630
24685
|
]);
|
|
24631
24686
|
return { order, fills, bids };
|
|
24632
24687
|
}
|
|
24688
|
+
/** The pairs the orderbook lists, and the smallest payout each token may carry. */
|
|
24689
|
+
books() {
|
|
24690
|
+
return this.service.books();
|
|
24691
|
+
}
|
|
24633
24692
|
/** Creates the order, posts it, and reports what the orderbook made of it. */
|
|
24634
24693
|
async create(request) {
|
|
24635
24694
|
const posted = await this.service.create(request);
|