@depthhq/maker-sdk 0.1.19 → 0.1.21

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/bot/bot.d.ts CHANGED
@@ -43,6 +43,7 @@ export declare class MakerBot {
43
43
  private cancel;
44
44
  private replace;
45
45
  tick(): Promise<BotSnapshot>;
46
+ private pricesChanged;
46
47
  private renew;
47
48
  private quotePolicy;
48
49
  private quoteRisk;
@@ -43,3 +43,4 @@ export declare function executionCosts(policy: BotPolicy, pricing?: Pick<BotPric
43
43
  export declare function validateBotPolicy(policy: BotPolicy): void;
44
44
  export declare function quoteHealth(market: BotMarket, now: number): string | undefined;
45
45
  export declare function botQuote(policy: BotPolicy, market: BotMarket, position: PositionSnapshot, nonce: bigint, now: number, pricing?: BotPricing, reservationCredit?: bigint): QuoteInput | undefined;
46
+ export declare function quotePrices(policy: BotPolicy, market: BotMarket, position: bigint, sizes: readonly bigint[], now: number, pricing?: BotPricing): QuoteInput["tiers"];
package/dist/node.js CHANGED
@@ -335,6 +335,17 @@ function botQuote(policy, market, position, nonce, now, pricing, reservationCred
335
335
  const tiers = quoteSizes(market.config.quoteTiers.map((value) => BigInt(value.toString())), capacity);
336
336
  if (!tiers.length)
337
337
  return;
338
+ const quotes = quotePrices(policy, market, position.position, tiers, now, pricing);
339
+ const duration = Math.min(policy.lifetimeSeconds, market.config.maxQuoteLifetimeSeconds);
340
+ return {
341
+ tiers: quotes,
342
+ maxCapacity: capacity,
343
+ expiresAt: now + duration,
344
+ clientNonce: nonce
345
+ };
346
+ }
347
+ function quotePrices(policy, market, position, sizes, now, pricing) {
348
+ const price = BigInt(market.oraclePriceE8.toString());
338
349
  const half = Math.ceil(policy.spreadBps / 2);
339
350
  const preparation = quoteBounds(market.config.maxQuoteDeviationBps).preparationBps;
340
351
  if (half > preparation)
@@ -343,7 +354,7 @@ function botQuote(policy, market, position, nonce, now, pricing, reservationCred
343
354
  validateBook(pricing.book, now * 1000, pricing.maxPriceAgeMs);
344
355
  if (pricing && (!Number.isFinite(pricing.takerFeeBps) || pricing.takerFeeBps < 0 || !Number.isFinite(pricing.hourlyFundingBps)))
345
356
  throw new Error("External execution costs are invalid");
346
- const netPosition = position.position + (pricing?.externalPosition ?? 0n);
357
+ const netPosition = position + (pricing?.externalPosition ?? 0n);
347
358
  const netExposure = notional(netPosition, price);
348
359
  const skewBps = netExposure * BigInt(policy.inventorySkewBps ?? 0) / policy.maxInventoryNotional;
349
360
  const boundedSkew = skewBps < BigInt(policy.inventorySkewBps ?? 0) ? skewBps : BigInt(policy.inventorySkewBps ?? 0);
@@ -352,7 +363,7 @@ function botQuote(policy, market, position, nonce, now, pricing, reservationCred
352
363
  const execution = executionCosts(policy, pricing);
353
364
  const bidCosts = costs + BigInt(execution.bid);
354
365
  const askCosts = costs + BigInt(execution.ask);
355
- const quotes = tiers.map((size) => {
366
+ return sizes.map((size) => {
356
367
  const units = (size * 100000000000n + price - 1n) / price;
357
368
  const sell = pricing ? executionPrice(pricing.book.bids, units) : price;
358
369
  const buy = pricing ? executionPrice(pricing.book.asks, units) : price;
@@ -363,13 +374,6 @@ function botQuote(policy, market, position, nonce, now, pricing, reservationCred
363
374
  throw new Error("Executable maker prices exceed oracle deviation bounds");
364
375
  return { size, bidE8, askE8 };
365
376
  });
366
- const duration = Math.min(policy.lifetimeSeconds, market.config.maxQuoteLifetimeSeconds);
367
- return {
368
- tiers: quotes,
369
- maxCapacity: capacity,
370
- expiresAt: now + duration,
371
- clientNonce: nonce
372
- };
373
377
  }
374
378
 
375
379
  // src/chain/clock.ts
@@ -841,6 +845,13 @@ class MakerBot {
841
845
  }
842
846
  const prior = this.maker.quote.get(new PublicKey2(replacement.prior));
843
847
  const previous = await prior.status();
848
+ if (snapshot.status === "validated" && this.pricesChanged(replacement.request, market, now)) {
849
+ await flow.discard();
850
+ state.replacement = undefined;
851
+ this.reservationView = undefined;
852
+ await this.store.save(state);
853
+ return this.snapshot("pending", "successor prices changed");
854
+ }
844
855
  if (previous.status === "active" && ["validated", "reserving"].includes(snapshot.status)) {
845
856
  const price = BigInt(market.oraclePriceE8.toString());
846
857
  const size = this.position.position;
@@ -916,8 +927,6 @@ class MakerBot {
916
927
  await this.hedge.tick(state.hedge, () => this.saveHedge(), undefined);
917
928
  return this.snapshot(stopped && !state.hedge?.pending ? "stopped" : "pending", reason);
918
929
  }
919
- if (state.quote)
920
- await this.renew(market, now);
921
930
  await this.fills();
922
931
  const hedgeReason = await this.hedgeTick();
923
932
  if (hedgeReason)
@@ -977,8 +986,19 @@ class MakerBot {
977
986
  const reference = BigInt(current.oracleReferenceE8.toString());
978
987
  const drift = price > reference ? price - reference : reference - price;
979
988
  const compatible = current.marketRevision.eq(market.revision) && drift * 10000n <= reference * BigInt(Math.min(Math.floor(market.config.maxQuoteDeviationBps / 4), 25));
980
- if (!this.dirty && !this.pricingDirty && compatible && current.expiry.toNumber() > now && difference !== undefined && difference < BigInt(this.policy.repriceBps) * state.referencePrice)
981
- return this.snapshot("active");
989
+ if (!this.dirty && !this.pricingDirty && compatible && current.expiry.toNumber() > now && difference !== undefined && difference < BigInt(this.policy.repriceBps) * state.referencePrice && state.request !== undefined && !this.pricesChanged(state.request, market, now)) {
990
+ if (await this.renew(market, now))
991
+ return this.snapshot("active");
992
+ market = await this.maker.read("Market", this.maker.marketAddress);
993
+ now = await chainTime(this.maker.options.connection);
994
+ const changed = quoteHealth(market, now);
995
+ if (changed) {
996
+ const stopped = await this.cancel();
997
+ return this.snapshot(stopped ? "stopped" : "pending", changed);
998
+ }
999
+ if ((await handle2.status()).status !== "active")
1000
+ return this.snapshot("pending", "quote changed during renewal");
1001
+ }
982
1002
  state.replacement = { prior: state.quote, nonce: nonce() };
983
1003
  this.pricingDirty = false;
984
1004
  await this.store.save(state);
@@ -1034,22 +1054,33 @@ class MakerBot {
1034
1054
  this.busy = false;
1035
1055
  }
1036
1056
  }
1057
+ pricesChanged(request, market, now) {
1058
+ if (this.position?.position === undefined)
1059
+ return true;
1060
+ const prices = quotePrices(this.policy, market, this.position.position, request.tiers.map((tier) => tier.size), now, this.pricing);
1061
+ return request.tiers.some((tier, index) => ["bidE8", "askE8"].some((side) => {
1062
+ const before = tier[side];
1063
+ const after = prices[index][side];
1064
+ const change = after > before ? after - before : before - after;
1065
+ return change * 10000n >= before * BigInt(this.policy.repriceBps);
1066
+ }));
1067
+ }
1037
1068
  async renew(market, now) {
1038
1069
  const state = this.state;
1039
1070
  if (this.hedge && (state.hedge?.pending || state.inventoryPendingSince !== undefined && Date.now() - state.inventoryPendingSince >= this.hedge.policy.maxUnhedgedMs))
1040
- return;
1071
+ return false;
1041
1072
  const handle = this.maker.quote.get(new PublicKey2(state.quote));
1042
1073
  const quote = await this.maker.quoteState(handle.id);
1043
1074
  if (!("active" in quote.status) || quote.expiry.toNumber() <= now)
1044
- return;
1075
+ return false;
1045
1076
  const duration = Math.min(this.policy.lifetimeSeconds, market.config.maxQuoteLifetimeSeconds);
1046
1077
  if (quote.expiry.toNumber() - now > Math.max(this.policy.refreshSeconds, duration - this.policy.refreshSeconds))
1047
- return;
1078
+ return true;
1048
1079
  const price = BigInt(market.oraclePriceE8.toString());
1049
1080
  const reference = BigInt(quote.oracleReferenceE8.toString());
1050
1081
  const drift = price > reference ? price - reference : reference - price;
1051
1082
  if (!quote.marketRevision.eq(market.revision) || reference <= 0n || drift * 10000n > reference * BigInt(Math.min(Math.floor(market.config.maxQuoteDeviationBps / 4), 25)))
1052
- return;
1083
+ return false;
1053
1084
  let renewed;
1054
1085
  try {
1055
1086
  renewed = await handle.renew({ validForSeconds: duration });
@@ -1065,12 +1096,13 @@ class MakerBot {
1065
1096
  const quotedPrice = BigInt(current.oracleReferenceE8.toString());
1066
1097
  const moved = currentPrice > quotedPrice ? currentPrice - quotedPrice : quotedPrice - currentPrice;
1067
1098
  if (!("active" in current.status) || current.expiry.toNumber() <= Math.floor(Date.now() / 1000) || !current.marketRevision.eq(latest.revision) || quoteHealth(latest, Math.floor(Date.now() / 1000)) || moved * 10000n > quotedPrice * BigInt(Math.min(Math.floor(latest.config.maxQuoteDeviationBps / 4), 25)))
1068
- return;
1099
+ return false;
1069
1100
  throw error;
1070
1101
  }
1071
1102
  if (state.request)
1072
1103
  state.request.expiresAt = renewed.expiresAt;
1073
1104
  await this.store.save(state);
1105
+ return true;
1074
1106
  }
1075
1107
  quotePolicy(market) {
1076
1108
  if (!this.hedge || !this.pricing || this.position?.position === undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depthhq/maker-sdk",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -30,7 +30,7 @@
30
30
  "buffer": "6.0.3",
31
31
  "viem": "2.38.0",
32
32
  "@depthhq/bindings": "0.1.5",
33
- "@depthhq/sdk": "0.1.11"
33
+ "@depthhq/sdk": "0.1.13"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "node ../../scripts/build-package.mjs maker-sdk",