@hyperbridge/sdk 2.8.16 → 2.8.18
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/browser/index.d.ts +144 -67
- package/dist/browser/index.js +150 -87
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +149 -87
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +141 -64
- package/dist/node/index.d.ts +141 -64
- package/dist/node/index.js +150 -87
- package/dist/node/index.js.map +1 -1
- package/package.json +1 -1
package/dist/node/index.cjs
CHANGED
|
@@ -18788,20 +18788,27 @@ var ROUTE_LIQUIDITY_QUERY = `
|
|
|
18788
18788
|
query RouteLiquidity($route: RouteInput!) {
|
|
18789
18789
|
books { id base quote }
|
|
18790
18790
|
routeLiquidity(route: $route) {
|
|
18791
|
-
route bestRate depthIn depthOut availableLiquidity maxFillableIn orderCount solverCount
|
|
18791
|
+
route bestRate slippageBps depthIn depthOut availableLiquidity maxFillableIn orderCount solverCount
|
|
18792
18792
|
}
|
|
18793
18793
|
}`;
|
|
18794
18794
|
var QUOTE_QUERY = `
|
|
18795
18795
|
query Quote($route: RouteInput!, $amountIn: BigInt!) {
|
|
18796
18796
|
quote(route: $route, amountIn: $amountIn) {
|
|
18797
|
-
route side amountIn
|
|
18798
|
-
fills { orderRate amountOut
|
|
18797
|
+
route side amountIn slippageBps fillable maxFillableIn
|
|
18798
|
+
fills { advertisedSize orderRate amountIn amountOut }
|
|
18799
|
+
}
|
|
18800
|
+
}`;
|
|
18801
|
+
var QUOTE_PESSIMISTIC_QUERY = `
|
|
18802
|
+
query QuotePessimistic($route: RouteInput!, $amountIn: BigInt!) {
|
|
18803
|
+
quotePessimistic(route: $route, amountIn: $amountIn) {
|
|
18804
|
+
route side amountIn amountOut rate priceBucket slippageBps fillable maxFillableIn
|
|
18799
18805
|
}
|
|
18800
18806
|
}`;
|
|
18801
18807
|
var ORDERBOOK_QUERIES = {
|
|
18802
18808
|
topOfBook: TOP_OF_BOOK_QUERY,
|
|
18803
18809
|
routeLiquidity: ROUTE_LIQUIDITY_QUERY,
|
|
18804
|
-
quote: QUOTE_QUERY
|
|
18810
|
+
quote: QUOTE_QUERY,
|
|
18811
|
+
quotePessimistic: QUOTE_PESSIMISTIC_QUERY
|
|
18805
18812
|
};
|
|
18806
18813
|
var HyperFxOrderbook = class {
|
|
18807
18814
|
client;
|
|
@@ -18830,8 +18837,9 @@ var HyperFxOrderbook = class {
|
|
|
18830
18837
|
return {
|
|
18831
18838
|
route: raw.route,
|
|
18832
18839
|
book,
|
|
18833
|
-
side: book.base
|
|
18834
|
-
bestRate:
|
|
18840
|
+
side: sameSymbol(book.base, route.tokenIn) ? "BID" : "ASK",
|
|
18841
|
+
bestRate: optionalBigInt(raw.bestRate),
|
|
18842
|
+
slippageBps: raw.slippageBps,
|
|
18835
18843
|
depthIn: BigInt(raw.depthIn),
|
|
18836
18844
|
depthOut: BigInt(raw.depthOut),
|
|
18837
18845
|
availableLiquidity: BigInt(raw.availableLiquidity),
|
|
@@ -18840,7 +18848,10 @@ var HyperFxOrderbook = class {
|
|
|
18840
18848
|
solverCount: raw.solverCount
|
|
18841
18849
|
};
|
|
18842
18850
|
}
|
|
18843
|
-
/**
|
|
18851
|
+
/**
|
|
18852
|
+
* The optimistic quote for `amountIn` (1e18 tokenIn) on a route: the route's orders, best price
|
|
18853
|
+
* first, each taking what it can at its own price. The fills' `amountOut`s sum to the output.
|
|
18854
|
+
*/
|
|
18844
18855
|
async quote(route, amountIn) {
|
|
18845
18856
|
const { quote: raw } = await this.request(QUOTE_QUERY, {
|
|
18846
18857
|
route,
|
|
@@ -18850,18 +18861,39 @@ var HyperFxOrderbook = class {
|
|
|
18850
18861
|
route: raw.route,
|
|
18851
18862
|
side: raw.side,
|
|
18852
18863
|
amountIn: BigInt(raw.amountIn),
|
|
18853
|
-
|
|
18854
|
-
rate: raw.rate === null ? null : BigInt(raw.rate),
|
|
18864
|
+
slippageBps: raw.slippageBps,
|
|
18855
18865
|
fillable: raw.fillable,
|
|
18856
|
-
depth: BigInt(raw.depth),
|
|
18857
18866
|
maxFillableIn: BigInt(raw.maxFillableIn),
|
|
18858
18867
|
fills: raw.fills.map((fill) => ({
|
|
18868
|
+
advertisedSize: BigInt(fill.advertisedSize),
|
|
18859
18869
|
orderRate: BigInt(fill.orderRate),
|
|
18860
|
-
|
|
18861
|
-
|
|
18870
|
+
amountIn: BigInt(fill.amountIn),
|
|
18871
|
+
amountOut: BigInt(fill.amountOut)
|
|
18862
18872
|
}))
|
|
18863
18873
|
};
|
|
18864
18874
|
}
|
|
18875
|
+
/**
|
|
18876
|
+
* The pessimistic quote for `amountIn` (1e18 tokenIn) on a route: one price, from the first level
|
|
18877
|
+
* deep enough to fill the whole trade by itself, at which every order in it fills; the route's
|
|
18878
|
+
* worst price when no one level can but its levels together can.
|
|
18879
|
+
*/
|
|
18880
|
+
async quotePessimistic(route, amountIn) {
|
|
18881
|
+
const { quotePessimistic: raw } = await this.request(
|
|
18882
|
+
QUOTE_PESSIMISTIC_QUERY,
|
|
18883
|
+
{ route, amountIn: amountIn.toString() }
|
|
18884
|
+
);
|
|
18885
|
+
return {
|
|
18886
|
+
route: raw.route,
|
|
18887
|
+
side: raw.side,
|
|
18888
|
+
amountIn: BigInt(raw.amountIn),
|
|
18889
|
+
amountOut: BigInt(raw.amountOut),
|
|
18890
|
+
rate: optionalBigInt(raw.rate),
|
|
18891
|
+
priceBucket: optionalBigInt(raw.priceBucket),
|
|
18892
|
+
slippageBps: raw.slippageBps,
|
|
18893
|
+
fillable: raw.fillable,
|
|
18894
|
+
maxFillableIn: BigInt(raw.maxFillableIn)
|
|
18895
|
+
};
|
|
18896
|
+
}
|
|
18865
18897
|
async request(query, variables) {
|
|
18866
18898
|
try {
|
|
18867
18899
|
return await this.client.request(query, variables);
|
|
@@ -18875,13 +18907,19 @@ function describeError(error) {
|
|
|
18875
18907
|
if (graphqlErrors?.length) return graphqlErrors.map((e) => e.message).join("; ");
|
|
18876
18908
|
return error instanceof Error ? error.message : String(error);
|
|
18877
18909
|
}
|
|
18910
|
+
function sameSymbol(a, b) {
|
|
18911
|
+
return a.toLowerCase() === b.toLowerCase();
|
|
18912
|
+
}
|
|
18878
18913
|
function findBook(books, tokenA, tokenB) {
|
|
18879
18914
|
const book = books.find(
|
|
18880
|
-
(b) => b.base
|
|
18915
|
+
(b) => sameSymbol(b.base, tokenA) && sameSymbol(b.quote, tokenB) || sameSymbol(b.base, tokenB) && sameSymbol(b.quote, tokenA)
|
|
18881
18916
|
);
|
|
18882
18917
|
if (!book) throw new OrderbookRequestError(`no book trades ${tokenA} for ${tokenB}`);
|
|
18883
18918
|
return book;
|
|
18884
18919
|
}
|
|
18920
|
+
function optionalBigInt(value) {
|
|
18921
|
+
return value === null ? null : BigInt(value);
|
|
18922
|
+
}
|
|
18885
18923
|
function parseRate(raw) {
|
|
18886
18924
|
return {
|
|
18887
18925
|
side: raw.side,
|
|
@@ -18923,18 +18961,6 @@ var OrderbookQuoteNotConvergedError = class extends Error {
|
|
|
18923
18961
|
rounds;
|
|
18924
18962
|
lastAmountIn;
|
|
18925
18963
|
};
|
|
18926
|
-
var InsufficientOrderbookLiquidityError = class extends Error {
|
|
18927
|
-
constructor(route, maxFillableIn) {
|
|
18928
|
-
super(
|
|
18929
|
-
`The HyperFX orderbook cannot fill ${route.tokenIn} -> ${route.tokenOut} on ${route.sourceChain} -> ${route.destinationChain}; max fillable input is ${maxFillableIn} raw units`
|
|
18930
|
-
);
|
|
18931
|
-
this.route = route;
|
|
18932
|
-
this.maxFillableIn = maxFillableIn;
|
|
18933
|
-
this.name = "InsufficientOrderbookLiquidityError";
|
|
18934
|
-
}
|
|
18935
|
-
route;
|
|
18936
|
-
maxFillableIn;
|
|
18937
|
-
};
|
|
18938
18964
|
|
|
18939
18965
|
// src/protocols/intents/orderbook/market.ts
|
|
18940
18966
|
var MAX_EXACT_OUTPUT_ROUNDS = 16;
|
|
@@ -18946,26 +18972,67 @@ var OrderbookMarket = class {
|
|
|
18946
18972
|
configService;
|
|
18947
18973
|
orderbook;
|
|
18948
18974
|
async quoteIntent(params, sourceChain, destinationChain) {
|
|
18975
|
+
const orderbook = this.orderbook();
|
|
18976
|
+
if (!params.optimistic) {
|
|
18977
|
+
const { quote: quote2, tokenIn: tokenIn2, tokenOut: tokenOut2 } = await this.priceIntent(
|
|
18978
|
+
params,
|
|
18979
|
+
sourceChain,
|
|
18980
|
+
destinationChain,
|
|
18981
|
+
(route, amountIn) => orderbook.quotePessimistic(route, amountIn),
|
|
18982
|
+
levelQuoteTotals
|
|
18983
|
+
);
|
|
18984
|
+
return {
|
|
18985
|
+
route: quote2.route,
|
|
18986
|
+
side: quote2.side,
|
|
18987
|
+
amountIn: fromOrderbookAmount(quote2.amountIn, tokenIn2.decimals),
|
|
18988
|
+
amountOut: fromOrderbookAmount(quote2.amountOut, tokenOut2.decimals),
|
|
18989
|
+
rate: quote2.rate,
|
|
18990
|
+
priceBucket: quote2.priceBucket,
|
|
18991
|
+
slippageBps: quote2.slippageBps,
|
|
18992
|
+
fillable: quote2.fillable,
|
|
18993
|
+
maxFillableIn: fromOrderbookAmount(quote2.maxFillableIn, tokenIn2.decimals)
|
|
18994
|
+
};
|
|
18995
|
+
}
|
|
18996
|
+
const { quote, tokenIn, tokenOut } = await this.priceIntent(
|
|
18997
|
+
params,
|
|
18998
|
+
sourceChain,
|
|
18999
|
+
destinationChain,
|
|
19000
|
+
(route, amountIn) => orderbook.quote(route, amountIn),
|
|
19001
|
+
swapQuoteTotals
|
|
19002
|
+
);
|
|
19003
|
+
return {
|
|
19004
|
+
route: quote.route,
|
|
19005
|
+
side: quote.side,
|
|
19006
|
+
amountIn: fromOrderbookAmount(quote.amountIn, tokenIn.decimals),
|
|
19007
|
+
slippageBps: quote.slippageBps,
|
|
19008
|
+
fillable: quote.fillable,
|
|
19009
|
+
maxFillableIn: fromOrderbookAmount(quote.maxFillableIn, tokenIn.decimals),
|
|
19010
|
+
legs: quote.fills.map((fill) => ({
|
|
19011
|
+
advertisedSize: fromOrderbookAmount(fill.advertisedSize, tokenOut.decimals),
|
|
19012
|
+
orderRate: fill.orderRate,
|
|
19013
|
+
amountIn: fromOrderbookAmount(fill.amountIn, tokenIn.decimals),
|
|
19014
|
+
amountOut: fromOrderbookAmount(fill.amountOut, tokenOut.decimals)
|
|
19015
|
+
}))
|
|
19016
|
+
};
|
|
19017
|
+
}
|
|
19018
|
+
/**
|
|
19019
|
+
* The orderbook's quote for an exact input, or for the input found to deliver
|
|
19020
|
+
* an exact output, with the assets it trades. A route that cannot fill the
|
|
19021
|
+
* trade answers with an unfillable quote rather than an error.
|
|
19022
|
+
*/
|
|
19023
|
+
async priceIntent(params, sourceChain, destinationChain, price, totals) {
|
|
18949
19024
|
validateQuoteParams(params);
|
|
18950
19025
|
const tokenIn = this.assetByAddress(sourceChain, params.tokenIn);
|
|
18951
19026
|
const tokenOut = this.assetByAddress(destinationChain, params.tokenOut);
|
|
18952
19027
|
const route = toRoute(tokenIn, tokenOut);
|
|
18953
19028
|
if (params.amountIn !== void 0) {
|
|
18954
|
-
const quote2 = await
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
return buildQuote("EXACT_INPUT", params.amountIn, amountOut2, quote2, tokenIn, tokenOut);
|
|
19029
|
+
const quote2 = await price(route, toOrderbookAmount(params.amountIn, tokenIn.decimals));
|
|
19030
|
+
totals(quote2);
|
|
19031
|
+
return { quote: quote2, tokenIn, tokenOut };
|
|
18958
19032
|
}
|
|
18959
|
-
const
|
|
18960
|
-
const quote = await this.quoteExactOutput(route,
|
|
18961
|
-
return
|
|
18962
|
-
"EXACT_OUTPUT",
|
|
18963
|
-
fromOrderbookAmount(quote.amountIn, tokenIn.decimals),
|
|
18964
|
-
amountOut,
|
|
18965
|
-
quote,
|
|
18966
|
-
tokenIn,
|
|
18967
|
-
tokenOut
|
|
18968
|
-
);
|
|
19033
|
+
const targetOut = toOrderbookAmount(params.amountOut, tokenOut.decimals);
|
|
19034
|
+
const quote = await this.quoteExactOutput(route, targetOut, tokenIn, price, totals);
|
|
19035
|
+
return { quote, tokenIn, tokenOut };
|
|
18969
19036
|
}
|
|
18970
19037
|
async availableLiquidity(params, sourceChain, destinationChain) {
|
|
18971
19038
|
const tokenIn = this.assetByAddress(sourceChain, params.tokenIn);
|
|
@@ -19018,22 +19085,29 @@ var OrderbookMarket = class {
|
|
|
19018
19085
|
}
|
|
19019
19086
|
/**
|
|
19020
19087
|
* The orderbook only quotes an input amount, so an output is priced by
|
|
19021
|
-
* guessing the input from the best rate
|
|
19022
|
-
*
|
|
19088
|
+
* guessing the input from the best rate, then keeping the part of each quote
|
|
19089
|
+
* filled better than its worst rate and re-pricing the rest of `targetOut` at
|
|
19090
|
+
* the input-to-output ratio that part filled at, until a quote delivers it.
|
|
19091
|
+
* That ratio is the orderbook's own, with the protocol fee already taken off.
|
|
19092
|
+
*
|
|
19093
|
+
* An output the route cannot deliver is answered by quoting an input past its
|
|
19094
|
+
* `maxFillableIn`, which the orderbook serves as unfillable: the smallest such
|
|
19095
|
+
* input guessed from the best rate, or one raw unit when no order serves it.
|
|
19023
19096
|
*/
|
|
19024
|
-
async quoteExactOutput(route, targetOut, tokenIn) {
|
|
19025
|
-
const
|
|
19026
|
-
const liquidity = await orderbook.routeLiquidity(route);
|
|
19027
|
-
if (liquidity.bestRate === null) throw this.insufficient(route, 0n, tokenIn);
|
|
19097
|
+
async quoteExactOutput(route, targetOut, tokenIn, price, totals) {
|
|
19098
|
+
const liquidity = await this.orderbook().routeLiquidity(route);
|
|
19028
19099
|
const inputUnit = toOrderbookAmount(1n, tokenIn.decimals);
|
|
19029
|
-
let amountIn = roundUpTo(requiredInput(liquidity.side, targetOut, liquidity.bestRate), inputUnit);
|
|
19100
|
+
let amountIn = liquidity.bestRate === null ? inputUnit : roundUpTo(requiredInput(liquidity.side, targetOut, liquidity.bestRate), inputUnit);
|
|
19030
19101
|
let lastAmountIn = amountIn;
|
|
19031
19102
|
for (let round = 0; round < MAX_EXACT_OUTPUT_ROUNDS; round++) {
|
|
19032
|
-
|
|
19033
|
-
const quote =
|
|
19034
|
-
if (quote.fillable && quote.amountOut >= targetOut) return
|
|
19103
|
+
const served = await price(route, amountIn);
|
|
19104
|
+
const quote = totals(served);
|
|
19105
|
+
if (quote.fillable && quote.amountOut >= targetOut) return served;
|
|
19106
|
+
if (!quote.fillable && amountIn > liquidity.maxFillableIn) return served;
|
|
19035
19107
|
lastAmountIn = amountIn;
|
|
19036
|
-
const
|
|
19108
|
+
const betterIn = quote.amountIn - quote.worstIn;
|
|
19109
|
+
const betterOut = quote.amountOut - quote.worstOut;
|
|
19110
|
+
const next = quote.fillable && quote.worstOut > 0n ? betterIn + roundUpTo(divCeil((targetOut - betterOut) * quote.worstIn, quote.worstOut), inputUnit) : amountIn;
|
|
19037
19111
|
amountIn = next > amountIn ? next : amountIn + inputUnit;
|
|
19038
19112
|
}
|
|
19039
19113
|
throw new OrderbookQuoteNotConvergedError(
|
|
@@ -19042,9 +19116,6 @@ var OrderbookMarket = class {
|
|
|
19042
19116
|
fromOrderbookAmount(lastAmountIn, tokenIn.decimals)
|
|
19043
19117
|
);
|
|
19044
19118
|
}
|
|
19045
|
-
insufficient(route, maxFillableIn, tokenIn) {
|
|
19046
|
-
return new InsufficientOrderbookLiquidityError(route, fromOrderbookAmount(maxFillableIn, tokenIn.decimals));
|
|
19047
|
-
}
|
|
19048
19119
|
assetByAddress(chain, address) {
|
|
19049
19120
|
const resolvedChain = resolveChain(chain);
|
|
19050
19121
|
return withDecimals(
|
|
@@ -19089,24 +19160,32 @@ function toRoute(tokenIn, tokenOut) {
|
|
|
19089
19160
|
function requiredInput(side, amountOut, rate) {
|
|
19090
19161
|
return side === "BID" ? divCeil(amountOut * ORDERBOOK_SCALE, rate) : divCeil(amountOut * rate, ORDERBOOK_SCALE);
|
|
19091
19162
|
}
|
|
19092
|
-
function
|
|
19093
|
-
|
|
19094
|
-
|
|
19163
|
+
function swapQuoteTotals(quote) {
|
|
19164
|
+
const worstFill = quote.fills.at(-1);
|
|
19165
|
+
if (quote.fillable && !worstFill)
|
|
19166
|
+
throw new OrderbookRequestError("the orderbook served a fillable quote with no fills");
|
|
19095
19167
|
return {
|
|
19096
|
-
|
|
19097
|
-
amountIn,
|
|
19098
|
-
amountOut,
|
|
19099
|
-
|
|
19100
|
-
|
|
19101
|
-
|
|
19102
|
-
|
|
19103
|
-
|
|
19104
|
-
|
|
19105
|
-
|
|
19106
|
-
|
|
19107
|
-
|
|
19108
|
-
|
|
19109
|
-
|
|
19168
|
+
side: quote.side,
|
|
19169
|
+
amountIn: quote.amountIn,
|
|
19170
|
+
amountOut: quote.fills.reduce((total, fill) => total + fill.amountOut, 0n),
|
|
19171
|
+
fillable: quote.fillable,
|
|
19172
|
+
maxFillableIn: quote.maxFillableIn,
|
|
19173
|
+
worstIn: worstFill?.amountIn ?? 0n,
|
|
19174
|
+
worstOut: worstFill?.amountOut ?? 0n
|
|
19175
|
+
};
|
|
19176
|
+
}
|
|
19177
|
+
function levelQuoteTotals(quote) {
|
|
19178
|
+
if (quote.fillable && quote.rate === null) {
|
|
19179
|
+
throw new OrderbookRequestError("the orderbook served a fillable quote with no rate");
|
|
19180
|
+
}
|
|
19181
|
+
return {
|
|
19182
|
+
side: quote.side,
|
|
19183
|
+
amountIn: quote.amountIn,
|
|
19184
|
+
amountOut: quote.amountOut,
|
|
19185
|
+
fillable: quote.fillable,
|
|
19186
|
+
maxFillableIn: quote.maxFillableIn,
|
|
19187
|
+
worstIn: quote.amountIn,
|
|
19188
|
+
worstOut: quote.amountOut
|
|
19110
19189
|
};
|
|
19111
19190
|
}
|
|
19112
19191
|
function toOrderbookAmount(amount, decimals) {
|
|
@@ -19270,22 +19349,6 @@ var IntentGateway = class _IntentGateway {
|
|
|
19270
19349
|
this.orderbook = typeof orderbook === "string" ? new HyperFxOrderbook(orderbook) : orderbook;
|
|
19271
19350
|
return this;
|
|
19272
19351
|
}
|
|
19273
|
-
/**
|
|
19274
|
-
* Quotes an intent between this gateway's source and destination chains from
|
|
19275
|
-
* the HyperFX orderbook. Provide exactly one of `amountIn` or `amountOut`, in
|
|
19276
|
-
* raw token units.
|
|
19277
|
-
*
|
|
19278
|
-
* An exact-input quote is the orderbook's clearing price for `amountIn`,
|
|
19279
|
-
* which may combine several solvers' orders. An exact-output quote finds the
|
|
19280
|
-
* smallest input whose clearing price delivers `amountOut`. A cross-chain
|
|
19281
|
-
* route only counts orders whose solvers accept the source chain.
|
|
19282
|
-
*
|
|
19283
|
-
* The orderbook's rates already carry the gateway protocol fee, so the
|
|
19284
|
-
* returned amounts can be placed as the order's inputs and outputs directly.
|
|
19285
|
-
*
|
|
19286
|
-
* @throws {InsufficientOrderbookLiquidityError} When the route cannot fill the amount.
|
|
19287
|
-
* @throws {OrderbookRequestError} When the orderbook is unreachable or trades no book for the pair.
|
|
19288
|
-
*/
|
|
19289
19352
|
async quoteIntent(params) {
|
|
19290
19353
|
return this.market.quoteIntent(params, this.source.config.stateMachineId, this.dest.config.stateMachineId);
|
|
19291
19354
|
}
|
|
@@ -24603,7 +24666,6 @@ exports.HyperFungibleToken = HyperFungibleToken;
|
|
|
24603
24666
|
exports.HyperFungibleTokenABI = HyperFungibleTokenABI;
|
|
24604
24667
|
exports.HyperFxOrderbook = HyperFxOrderbook;
|
|
24605
24668
|
exports.INCLUSION_TIMEOUT_MS = INCLUSION_TIMEOUT_MS;
|
|
24606
|
-
exports.InsufficientOrderbookLiquidityError = InsufficientOrderbookLiquidityError;
|
|
24607
24669
|
exports.IntentGateway = IntentGateway;
|
|
24608
24670
|
exports.IntentGatewayABI = ABI3;
|
|
24609
24671
|
exports.IntentOrderStatus = IntentOrderStatus;
|