@symmio/trading-react 0.1.1 → 1.0.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.
Files changed (221) hide show
  1. package/README.md +2 -2
  2. package/dist/account-layer/index.d.ts +28 -28
  3. package/dist/account-layer/index.js +29 -0
  4. package/dist/account-layer/use-account-balance-info.d.ts +16 -5
  5. package/dist/account-layer/use-account-balance-info.d.ts.map +1 -1
  6. package/dist/account-layer/use-account-balance-info.js +21 -9
  7. package/dist/account-layer/use-account-balance-info.js.map +1 -1
  8. package/dist/account-layer/use-account-balance-of.d.ts +16 -5
  9. package/dist/account-layer/use-account-balance-of.d.ts.map +1 -1
  10. package/dist/account-layer/use-account-balance-of.js +20 -9
  11. package/dist/account-layer/use-account-balance-of.js.map +1 -1
  12. package/dist/account-layer/use-add-margin.d.ts +2 -2
  13. package/dist/account-layer/use-allocate.d.ts +2 -2
  14. package/dist/account-layer/use-create-sub-accounts.d.ts +2 -2
  15. package/dist/account-layer/use-deallocate.d.ts +2 -2
  16. package/dist/account-layer/use-delete-sub-account.d.ts +2 -2
  17. package/dist/account-layer/use-deposit-and-allocate.d.ts +2 -2
  18. package/dist/account-layer/use-deposit.d.ts +5 -3
  19. package/dist/account-layer/use-deposit.d.ts.map +1 -1
  20. package/dist/account-layer/use-deposit.js +17 -15
  21. package/dist/account-layer/use-deposit.js.map +1 -1
  22. package/dist/account-layer/use-edit-account-name.d.ts +2 -2
  23. package/dist/account-layer/use-predicted-next-virtual-account.d.ts +1 -1
  24. package/dist/account-layer/use-remove-margin.d.ts +2 -2
  25. package/dist/account-layer/use-simulate-add-margin.d.ts +1 -1
  26. package/dist/account-layer/use-simulate-allocate.d.ts +1 -1
  27. package/dist/account-layer/use-simulate-create-sub-accounts.d.ts +1 -1
  28. package/dist/account-layer/use-simulate-deallocate.d.ts +1 -1
  29. package/dist/account-layer/use-simulate-delete-sub-account.d.ts +1 -1
  30. package/dist/account-layer/use-simulate-deposit-and-allocate.d.ts +1 -1
  31. package/dist/account-layer/use-simulate-deposit.d.ts +1 -1
  32. package/dist/account-layer/use-simulate-edit-account-name.d.ts +1 -1
  33. package/dist/account-layer/use-simulate-remove-margin.d.ts +1 -1
  34. package/dist/account-layer/use-sub-account-virtual-nonce.d.ts +1 -1
  35. package/dist/account-layer/use-sub-account.d.ts +1 -1
  36. package/dist/account-layer/use-sub-accounts-count-of-user.d.ts +1 -1
  37. package/dist/account-layer/use-user-sub-accounts-addresses.d.ts +1 -1
  38. package/dist/account-layer/use-user-sub-accounts.d.ts +1 -1
  39. package/dist/account-layer/use-virtual-account.d.ts +1 -1
  40. package/dist/account-layer/use-virtual-accounts-addresses-of-sub-account.d.ts +1 -1
  41. package/dist/balance-history/index.d.ts +3 -3
  42. package/dist/balance-history/use-balance-history.d.ts +1 -1
  43. package/dist/balance-history/use-deposit-history.d.ts +1 -1
  44. package/dist/balance-history/use-withdraw-history.d.ts +1 -1
  45. package/dist/collateral/index.d.ts +4 -4
  46. package/dist/collateral/use-approve-collateral.d.ts +2 -2
  47. package/dist/collateral/use-collateral-allowance.d.ts +1 -1
  48. package/dist/collateral/use-collateral-balance.d.ts +1 -1
  49. package/dist/collateral/use-simulate-approve-collateral.d.ts +1 -1
  50. package/dist/error-codes/index.d.ts +2 -2
  51. package/dist/error-codes/use-solver-error-codes.d.ts +1 -1
  52. package/dist/error-codes/use-solver-error-message.d.ts +1 -1
  53. package/dist/errors/index.d.ts +3 -3
  54. package/dist/errors/index.js +3 -0
  55. package/dist/errors/normalize-symm-error.d.ts +1 -1
  56. package/dist/errors/symmio-request-error.d.ts +1 -1
  57. package/dist/estimated-price/index.d.ts +2 -0
  58. package/dist/estimated-price/index.d.ts.map +1 -0
  59. package/dist/estimated-price/use-debounced-value.d.ts +9 -0
  60. package/dist/estimated-price/use-debounced-value.d.ts.map +1 -0
  61. package/dist/estimated-price/use-debounced-value.js +18 -0
  62. package/dist/estimated-price/use-debounced-value.js.map +1 -0
  63. package/dist/estimated-price/use-estimated-price.d.ts +46 -0
  64. package/dist/estimated-price/use-estimated-price.d.ts.map +1 -0
  65. package/dist/estimated-price/use-estimated-price.js +31 -0
  66. package/dist/estimated-price/use-estimated-price.js.map +1 -0
  67. package/dist/fees/index.d.ts +1 -1
  68. package/dist/fees/index.js +2 -0
  69. package/dist/fees/use-fee-for-user.d.ts +1 -1
  70. package/dist/funding-info/index.d.ts +2 -0
  71. package/dist/funding-info/index.d.ts.map +1 -0
  72. package/dist/funding-info/use-funding-info.d.ts +25 -0
  73. package/dist/funding-info/use-funding-info.d.ts.map +1 -0
  74. package/dist/funding-info/use-funding-info.js +27 -0
  75. package/dist/funding-info/use-funding-info.js.map +1 -0
  76. package/dist/index.d.ts +45 -24
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +120 -113
  79. package/dist/instant-layer/index.d.ts +14 -13
  80. package/dist/instant-layer/index.d.ts.map +1 -1
  81. package/dist/instant-layer/index.js +15 -0
  82. package/dist/instant-layer/use-delegation-expiry.d.ts +1 -1
  83. package/dist/instant-layer/use-grant-delegation.d.ts +2 -2
  84. package/dist/instant-layer/use-instant-close-auto.d.ts +1 -1
  85. package/dist/instant-layer/use-instant-close-bulk-auto.d.ts +1 -1
  86. package/dist/instant-layer/use-instant-close-bulk.d.ts +1 -1
  87. package/dist/instant-layer/use-instant-close.d.ts +1 -1
  88. package/dist/instant-layer/use-instant-closes.d.ts +1 -1
  89. package/dist/instant-layer/use-instant-open-auto.d.ts +1 -1
  90. package/dist/instant-layer/use-instant-open-quote-id.d.ts +1 -1
  91. package/dist/instant-layer/use-instant-open-with-tpsl.d.ts +55 -0
  92. package/dist/instant-layer/use-instant-open-with-tpsl.d.ts.map +1 -0
  93. package/dist/instant-layer/use-instant-open-with-tpsl.js +64 -0
  94. package/dist/instant-layer/use-instant-open-with-tpsl.js.map +1 -0
  95. package/dist/instant-layer/use-instant-open.d.ts +1 -1
  96. package/dist/instant-layer/use-instant-opens.d.ts +1 -1
  97. package/dist/instant-layer/use-is-delegation-active.d.ts +1 -1
  98. package/dist/instant-layer/use-simulate-grant-delegation.d.ts +1 -1
  99. package/dist/locked-params/index.d.ts +1 -1
  100. package/dist/locked-params/use-locked-params.d.ts +1 -1
  101. package/dist/margin/index.d.ts +2 -0
  102. package/dist/margin/index.d.ts.map +1 -0
  103. package/dist/margin/use-available-instant-open-margin.d.ts +51 -0
  104. package/dist/margin/use-available-instant-open-margin.d.ts.map +1 -0
  105. package/dist/margin/use-available-instant-open-margin.js +66 -0
  106. package/dist/margin/use-available-instant-open-margin.js.map +1 -0
  107. package/dist/market-info/index.d.ts +2 -0
  108. package/dist/market-info/index.d.ts.map +1 -0
  109. package/dist/market-info/use-market-info.d.ts +28 -0
  110. package/dist/market-info/use-market-info.d.ts.map +1 -0
  111. package/dist/market-info/use-market-info.js +27 -0
  112. package/dist/market-info/use-market-info.js.map +1 -0
  113. package/dist/markets/index.d.ts +2 -2
  114. package/dist/markets/index.js +3 -0
  115. package/dist/markets/use-markets.d.ts +1 -1
  116. package/dist/markets/use-onchain-contract-markets.d.ts +1 -1
  117. package/dist/muon/index.d.ts +10 -10
  118. package/dist/muon/use-deallocate-upnl-sig.d.ts +1 -1
  119. package/dist/muon/use-muon-party-a-overview.d.ts +1 -1
  120. package/dist/muon/use-muon-price-range.d.ts +1 -1
  121. package/dist/muon/use-muon-price.d.ts +1 -1
  122. package/dist/muon/use-muon-settle-upnl.d.ts +1 -1
  123. package/dist/muon/use-muon-upnl-a-with-symbol-price.d.ts +1 -1
  124. package/dist/muon/use-muon-upnl-a.d.ts +1 -1
  125. package/dist/muon/use-muon-upnl-b.d.ts +1 -1
  126. package/dist/muon/use-muon-upnl-with-symbol-price.d.ts +1 -1
  127. package/dist/muon/use-muon-upnl.d.ts +1 -1
  128. package/dist/notifications/index.d.ts +1 -1
  129. package/dist/notifications/use-search-notifications.d.ts +1 -1
  130. package/dist/notional-cap/index.d.ts +3 -3
  131. package/dist/notional-cap/use-notional-cap-all.d.ts +1 -1
  132. package/dist/notional-cap/use-notional-cap-by-symbol-id.d.ts +1 -1
  133. package/dist/notional-cap/use-open-interest-by-symbol-id.d.ts +1 -1
  134. package/dist/price-service/index.d.ts +8 -8
  135. package/dist/price-service/index.js +9 -0
  136. package/dist/price-service/use-enigma-price-by-market-id.d.ts +1 -1
  137. package/dist/price-service/use-enigma-price-by-name.d.ts +1 -1
  138. package/dist/price-service/use-enigma-price-service-health.d.ts +1 -1
  139. package/dist/price-service/use-enigma-price-service-metadata.d.ts +1 -1
  140. package/dist/price-service/use-enigma-price-service-prices-by-addresses.d.ts +1 -1
  141. package/dist/price-service/use-enigma-price-service-prices-by-names.d.ts +1 -1
  142. package/dist/price-service/use-enigma-price-service-symbols-info.d.ts +1 -1
  143. package/dist/price-service/use-enigma-prices.d.ts +1 -1
  144. package/dist/provider/index.d.ts +3 -3
  145. package/dist/provider/index.js +4 -0
  146. package/dist/provider/symmio-provider.d.ts +14 -5
  147. package/dist/provider/symmio-provider.d.ts.map +1 -1
  148. package/dist/provider/symmio-provider.js +2 -2
  149. package/dist/provider/symmio-provider.js.map +1 -1
  150. package/dist/quotes/index.d.ts +15 -15
  151. package/dist/quotes/use-account-liquidation-price.d.ts +4 -7
  152. package/dist/quotes/use-account-liquidation-price.d.ts.map +1 -1
  153. package/dist/quotes/use-account-liquidation-price.js.map +1 -1
  154. package/dist/quotes/use-grouped-quotes.d.ts +1 -1
  155. package/dist/quotes/use-managed-quotes.d.ts +1 -1
  156. package/dist/quotes/use-managed-quotes.d.ts.map +1 -1
  157. package/dist/quotes/use-managed-quotes.js +131 -128
  158. package/dist/quotes/use-managed-quotes.js.map +1 -1
  159. package/dist/quotes/use-party-a-open-positions.d.ts +4 -4
  160. package/dist/quotes/use-party-a-open-positions.js.map +1 -1
  161. package/dist/quotes/use-party-a-pending-quotes.d.ts +1 -1
  162. package/dist/quotes/use-quote-events-by-type.d.ts +1 -1
  163. package/dist/quotes/use-quote-funding.d.ts +1 -1
  164. package/dist/quotes/use-quote-history.d.ts +1 -1
  165. package/dist/quotes/use-quote-price-history.d.ts +1 -1
  166. package/dist/quotes/use-quote.d.ts +1 -1
  167. package/dist/quotes/use-quotes-funding.d.ts +1 -1
  168. package/dist/quotes/use-subgraph-query.d.ts +1 -1
  169. package/dist/tpsl/index.d.ts +8 -7
  170. package/dist/tpsl/index.d.ts.map +1 -1
  171. package/dist/tpsl/tpsl-store.d.ts +84 -0
  172. package/dist/tpsl/tpsl-store.d.ts.map +1 -0
  173. package/dist/tpsl/tpsl-store.js +154 -0
  174. package/dist/tpsl/tpsl-store.js.map +1 -0
  175. package/dist/tpsl/use-delete-quote-tpsl.d.ts +15 -0
  176. package/dist/tpsl/use-delete-quote-tpsl.d.ts.map +1 -0
  177. package/dist/tpsl/use-delete-quote-tpsl.js +31 -0
  178. package/dist/tpsl/use-delete-quote-tpsl.js.map +1 -0
  179. package/dist/tpsl/use-quote-tpsl.d.ts +19 -20
  180. package/dist/tpsl/use-quote-tpsl.d.ts.map +1 -1
  181. package/dist/tpsl/use-quote-tpsl.js +24 -53
  182. package/dist/tpsl/use-quote-tpsl.js.map +1 -1
  183. package/dist/tpsl/use-set-quote-tpsl.d.ts +11 -10
  184. package/dist/tpsl/use-set-quote-tpsl.d.ts.map +1 -1
  185. package/dist/tpsl/use-set-quote-tpsl.js +18 -22
  186. package/dist/tpsl/use-set-quote-tpsl.js.map +1 -1
  187. package/dist/tpsl/use-tpsl-config.d.ts +1 -1
  188. package/dist/tpsl/use-tpsl-signing-spec.d.ts +1 -1
  189. package/dist/tpsl/use-watch-tpsl-notifications.d.ts +1 -1
  190. package/dist/transactions/index.d.ts +3 -3
  191. package/dist/transactions/index.js +3 -0
  192. package/dist/transactions/resolve-write-result.d.ts +1 -1
  193. package/dist/transfers/index.d.ts +1 -1
  194. package/dist/transfers/use-transfer-history.d.ts +1 -1
  195. package/dist/utils/index.d.ts +1 -1
  196. package/dist/wallet/index.d.ts +4 -4
  197. package/dist/wallet/index.js +5 -0
  198. package/dist/wallet/use-connect-wallet.d.ts +1 -1
  199. package/dist/wallet/use-switch-to-symmio-chain.d.ts +1 -1
  200. package/dist/websocket/index.d.ts +1 -1
  201. package/dist/websocket/is-settle-notification.d.ts +15 -0
  202. package/dist/websocket/is-settle-notification.d.ts.map +1 -0
  203. package/dist/websocket/is-settle-notification.js +15 -0
  204. package/dist/websocket/is-settle-notification.js.map +1 -0
  205. package/dist/websocket/use-notifications.d.ts +1 -1
  206. package/dist/withdraw/index.d.ts +10 -10
  207. package/dist/withdraw/use-finalize-withdraw-request.d.ts +2 -2
  208. package/dist/withdraw/use-initiate-withdraw.d.ts +2 -2
  209. package/dist/withdraw/use-last-withdraw-request-id.d.ts +1 -1
  210. package/dist/withdraw/use-pending-withdraw-requests.d.ts +1 -1
  211. package/dist/withdraw/use-request-cancel-withdraw.d.ts +2 -2
  212. package/dist/withdraw/use-simulate-finalize-withdraw-request.d.ts +1 -1
  213. package/dist/withdraw/use-simulate-initiate-withdraw.d.ts +1 -1
  214. package/dist/withdraw/use-simulate-request-cancel-withdraw.d.ts +1 -1
  215. package/dist/withdraw/use-withdraw-requests.d.ts +1 -1
  216. package/dist/withdraw/use-withdrawable-time.d.ts +1 -1
  217. package/package.json +11 -10
  218. package/dist/tpsl/tpsl-confirming.d.ts +0 -36
  219. package/dist/tpsl/tpsl-confirming.d.ts.map +0 -1
  220. package/dist/tpsl/tpsl-confirming.js +0 -28
  221. package/dist/tpsl/tpsl-confirming.js.map +0 -1
@@ -2,163 +2,166 @@
2
2
  import { useSymmioChainId as e } from "../provider/use-symmio-chain-id.js";
3
3
  import { useSymmioConfig as t } from "../provider/use-symmio-config.js";
4
4
  import { normalizeSymmError as n } from "../errors/normalize-symm-error.js";
5
- import { predicateMatch as r } from "../utils/predicate-match.js";
6
- import { useVirtualAccountsAddressesOfSubAccount as i } from "../account-layer/use-virtual-accounts-addresses-of-sub-account.js";
7
- import { useInstantCloses as a } from "../instant-layer/use-instant-closes.js";
8
- import { useInstantOpens as ee } from "../instant-layer/use-instant-opens.js";
9
- import { useOptimisticQuotesStore as te } from "./optimistic-quotes-store.js";
10
- import { useNotifications as ne } from "../websocket/use-notifications.js";
11
- import { QuoteLifecycle as o, classifyQuoteNotificationAction as re, getInstantClosesQueryKey as ie, getInstantOpensQueryKey as s, getPartyAOpenPositionsQueryKey as c, getPartyAOpenPositionsQueryOptions as ae, getPartyAPendingQuotesQueryKey as l, getPartyAPendingQuotesQueryOptions as oe, getPredictedNextVirtualAccountQueryOptions as se, getQuoteQueryKey as ce, getQuoteQueryOptions as le, isolationTypeForSide as ue, reconcileQuotes as de, shouldAccelerateOnchainReads as fe } from "@symmio/trading-core";
12
- import { useCallback as pe, useEffect as u, useMemo as d, useRef as f, useState as me } from "react";
13
- import { getAddress as p } from "viem";
14
- import { useQueries as m, useQueryClient as he } from "@tanstack/react-query";
5
+ import { useNotifications as r } from "../websocket/use-notifications.js";
6
+ import { predicateMatch as i } from "../utils/predicate-match.js";
7
+ import { useVirtualAccountsAddressesOfSubAccount as a } from "../account-layer/use-virtual-accounts-addresses-of-sub-account.js";
8
+ import { useInstantCloses as ee } from "../instant-layer/use-instant-closes.js";
9
+ import { useTpSlStore as te } from "../tpsl/tpsl-store.js";
10
+ import { useInstantOpens as ne } from "../instant-layer/use-instant-opens.js";
11
+ import { useOptimisticQuotesStore as o } from "./optimistic-quotes-store.js";
12
+ import { QuoteLifecycle as s, classifyQuoteNotificationAction as re, getInstantClosesQueryKey as c, getInstantOpensQueryKey as l, getPartyAOpenPositionsQueryKey as u, getPartyAOpenPositionsQueryOptions as ie, getPartyAPendingQuotesQueryKey as ae, getPartyAPendingQuotesQueryOptions as oe, getPredictedNextVirtualAccountQueryOptions as se, getQuoteQueryKey as ce, getQuoteQueryOptions as le, isolationTypeForSide as ue, reconcileQuotes as de, shouldAccelerateOnchainReads as fe } from "@symmio/trading-core";
13
+ import { useCallback as d, useEffect as f, useMemo as p, useRef as m, useState as h } from "react";
14
+ import { getAddress as g } from "viem";
15
+ import { useQueries as _, useQueryClient as pe } from "@tanstack/react-query";
15
16
  //#region src/quotes/use-managed-quotes.ts
16
- var ge = 5e3, _e = 1500, ve = 100, ye = [], be = 250, xe = new Set([
17
- o.OPTIMISTIC,
18
- o.PRICE_FILLED,
19
- o.WRITE_ONCHAIN
20
- ]), Se = new Set([o.WRITE_ONCHAIN_CLOSE, o.CLOSING]);
21
- function h(o) {
22
- let { partyA: h, chainId: Ce, pollingInterval: g, live: _ = !0, enabled: we = !0 } = o, v = t(), Te = e(), y = Ce ?? Te, b = o.includeVirtualAccounts ?? !0, Ee = o.extraAccounts, x = o.sources, S = x?.openPositions ?? !0, C = x?.pendingQuotes ?? !0, w = x?.instantOpens ?? !0, T = x?.instantCloses ?? !0, E = we && !!h, D = E && h ? `${y}:${h.toLowerCase()}` : void 0, [O, De] = me({ vas: [] }), k = O.owner === D ? O.vas : ye, A = he(), j = f(A);
23
- j.current = A;
24
- let Oe = v.getChainConfigKey(y), M = f(Oe);
25
- M.current = Oe;
26
- let N = f(void 0), P = f({
17
+ var me = 5e3, he = 1500, ge = 100, _e = [], ve = 250, ye = new Set([
18
+ s.OPTIMISTIC,
19
+ s.PRICE_FILLED,
20
+ s.WRITE_ONCHAIN
21
+ ]), be = new Set([s.WRITE_ONCHAIN_CLOSE, s.CLOSING]);
22
+ function v(s) {
23
+ let { partyA: v, chainId: xe, pollingInterval: y, live: b = !0, enabled: Se = !0 } = s, x = t(), Ce = e(), S = xe ?? Ce, C = s.includeVirtualAccounts ?? !0, w = s.extraAccounts, T = s.sources, E = T?.openPositions ?? !0, D = T?.pendingQuotes ?? !0, O = T?.instantOpens ?? !0, k = T?.instantCloses ?? !0, A = Se && !!v, j = A && v ? `${S}:${v.toLowerCase()}` : void 0, [we, Te] = h({ vas: [] }), Ee = we.owner === j ? we.vas : _e, De = pe(), M = m(De);
24
+ M.current = De;
25
+ let Oe = x.getChainConfigKey(S), N = m(Oe);
26
+ N.current = Oe;
27
+ let P = m(void 0), F = m({
27
28
  opens: !1,
28
29
  closes: !1
29
- }), F = f(void 0), I = f([]), L = f("closed"), R = te((e) => e.entries), ke = te((e) => e.clearSettled), Ae = _ && L.current === "open", z = g && g > 0 ? g : !1, je = F.current ? fe(F.current) : !1, B = E ? je ? _e : Ae ? z : z || ge : !1, Me = F.current?.quotes, Ne = Me?.some((e) => xe.has(e.lifecycle)) ?? !1, Pe = Me?.some((e) => Se.has(e.lifecycle)) ?? !1, Fe = (e) => !Ae && e ? _e : z, Ie = E && w ? Fe(Ne) : !1, Le = E && T ? Fe(Pe) : !1, V = ee({
30
- partyA: h,
31
- chainId: y,
30
+ }), I = m(void 0), L = m([]), ke = m("closed"), R = o((e) => e.entries), Ae = o((e) => e.clearSettled), je = b && ke.current === "open", z = y && y > 0 ? y : !1, Me = I.current ? fe(I.current) : !1, B = A ? Me ? he : je ? z : z || me : !1, Ne = I.current?.quotes, Pe = Ne?.some((e) => ye.has(e.lifecycle)) ?? !1, Fe = Ne?.some((e) => be.has(e.lifecycle)) ?? !1, Ie = (e) => !je && e ? he : z, Le = A && O ? Ie(Pe) : !1, Re = A && k ? Ie(Fe) : !1, V = ne({
31
+ partyA: v,
32
+ chainId: S,
32
33
  query: {
33
- enabled: E && w,
34
- refetchInterval: Ie
34
+ enabled: A && O,
35
+ refetchInterval: Le
35
36
  }
36
- }), H = a({
37
- partyA: h,
38
- chainId: y,
37
+ }), H = ee({
38
+ partyA: v,
39
+ chainId: S,
39
40
  query: {
40
- enabled: E && T,
41
- refetchInterval: Le
41
+ enabled: A && k,
42
+ refetchInterval: Re
42
43
  }
43
- }), U = i({
44
- subAccount: h,
45
- chainId: y,
44
+ }), U = a({
45
+ subAccount: v,
46
+ chainId: S,
46
47
  query: {
47
- enabled: E && b,
48
+ enabled: A && C,
48
49
  refetchInterval: B
49
50
  }
50
- }), Re = w ? V.data ?? [] : [], W = m({
51
- queries: Re.map((e) => ({ ...se(v, {
52
- subAccount: h,
53
- chainId: y,
51
+ }), ze = O ? V.data ?? [] : [], W = _({
52
+ queries: ze.map((e) => ({ ...se(x, {
53
+ subAccount: v,
54
+ chainId: S,
54
55
  isolationType: ue(e.positionType),
55
56
  symbolId: BigInt(e.marketId),
56
57
  query: {
57
- enabled: E && b,
58
+ enabled: A && C,
58
59
  refetchInterval: B
59
60
  }
60
61
  }) })),
61
62
  combine: (e) => ({
62
- byTempId: Re.reduce((t, n, r) => {
63
+ byTempId: ze.reduce((t, n, r) => {
63
64
  let i = e[r]?.data;
64
- return i && (t[n.tempQuoteId] = p(i)), t;
65
+ return i && (t[n.tempQuoteId] = g(i)), t;
65
66
  }, {}),
66
67
  addresses: e.map((e) => e.data).filter((e) => !!e),
67
68
  isLoading: e.some((e) => e.isLoading),
68
69
  isFetching: e.some((e) => e.isFetching)
69
70
  })
70
- }), [G, ze] = me([]), { status: K } = ne({
71
- account: h,
72
- chainId: y,
73
- enabled: E && _,
74
- onNotification: pe((e) => {
75
- ze((t) => [...t, e].slice(-ve));
76
- let t = re(e.lastSeenAction), n = P.current;
77
- t === "open" ? n.opens = !0 : (t === "close" || (n.opens = !0), n.closes = !0), N.current && clearTimeout(N.current), N.current = setTimeout(() => {
78
- let e = j.current, t = { configKey: M.current }, { opens: n, closes: i } = P.current;
79
- P.current = {
71
+ }), [G, Be] = h([]), { status: K } = r({
72
+ account: v,
73
+ chainId: S,
74
+ enabled: A && b,
75
+ onNotification: d((e) => {
76
+ Be((t) => [...t, e].slice(-ge));
77
+ let t = e.tempQuoteId, n = e.quoteId;
78
+ t && n && n !== `${t}` && te.getState().link(BigInt(t), BigInt(n));
79
+ let r = re(e.lastSeenAction), a = F.current;
80
+ r === "open" ? a.opens = !0 : (r === "close" || (a.opens = !0), a.closes = !0), P.current && clearTimeout(P.current), P.current = setTimeout(() => {
81
+ let e = M.current, t = { configKey: N.current }, { opens: n, closes: r } = F.current;
82
+ F.current = {
80
83
  opens: !1,
81
84
  closes: !1
82
- }, e.invalidateQueries({ predicate: r(c, t) }), e.invalidateQueries({ predicate: r(l, t) }), e.invalidateQueries({ predicate: r(ce, t) }), n && e.invalidateQueries({ predicate: r(s, t) }), i && e.invalidateQueries({ predicate: r(ie, t) });
83
- }, be);
85
+ }, e.invalidateQueries({ predicate: i(u, t) }), e.invalidateQueries({ predicate: i(ae, t) }), e.invalidateQueries({ predicate: i(ce, t) }), n && e.invalidateQueries({ predicate: i(l, t) }), r && e.invalidateQueries({ predicate: i(c, t) });
86
+ }, ve);
84
87
  }, [])
85
88
  });
86
- L.current = K;
87
- let Be = f(!1);
88
- u(() => {
89
- if (!(!_ || K !== "open")) {
90
- if (Be.current) {
91
- let e = j.current, t = { configKey: M.current };
92
- e.invalidateQueries({ predicate: r(c, t) }), e.invalidateQueries({ predicate: r(l, t) }), e.invalidateQueries({ predicate: r(ce, t) }), e.invalidateQueries({ predicate: r(s, t) }), e.invalidateQueries({ predicate: r(ie, t) });
89
+ ke.current = K;
90
+ let Ve = m(!1);
91
+ f(() => {
92
+ if (!(!b || K !== "open")) {
93
+ if (Ve.current) {
94
+ let e = M.current, t = { configKey: N.current };
95
+ e.invalidateQueries({ predicate: i(u, t) }), e.invalidateQueries({ predicate: i(ae, t) }), e.invalidateQueries({ predicate: i(ce, t) }), e.invalidateQueries({ predicate: i(l, t) }), e.invalidateQueries({ predicate: i(c, t) });
93
96
  }
94
- Be.current = !0;
97
+ Ve.current = !0;
95
98
  }
96
- }, [K, _]), u(() => () => {
97
- N.current && clearTimeout(N.current);
99
+ }, [K, b]), f(() => () => {
100
+ P.current && clearTimeout(P.current);
98
101
  }, []);
99
- let q = d(() => {
102
+ let q = p(() => {
100
103
  let e = /* @__PURE__ */ new Set(), t = [];
101
104
  for (let n of G) {
102
105
  if (!n.vaAddress) continue;
103
- let r = p(n.vaAddress), i = r.toLowerCase();
106
+ let r = g(n.vaAddress), i = r.toLowerCase();
104
107
  e.has(i) || (e.add(i), t.push(r));
105
108
  }
106
109
  return t;
107
- }, [G]), J = d(() => {
108
- if (!E || !h) return [];
110
+ }, [G]), J = p(() => {
111
+ if (!A || !v) return [];
109
112
  let e = /* @__PURE__ */ new Set(), t = [], n = (n) => {
110
- let r = p(n), i = r.toLowerCase();
113
+ let r = g(n), i = r.toLowerCase();
111
114
  e.has(i) || (e.add(i), t.push(r));
112
115
  };
113
- if (n(h), b) {
116
+ if (n(v), C) {
114
117
  for (let e of U.data ?? []) n(e);
115
118
  for (let e of W.addresses) n(e);
116
119
  for (let e of q) n(e);
117
- for (let e of k) n(e);
120
+ for (let e of Ee) n(e);
118
121
  }
119
- for (let e of Ee ?? []) n(e);
122
+ for (let e of w ?? []) n(e);
120
123
  return t;
121
124
  }, [
122
- E,
123
- h,
124
- b,
125
+ A,
126
+ v,
127
+ C,
125
128
  U.data,
126
129
  W.addresses,
127
130
  q,
128
- k,
129
- Ee
131
+ Ee,
132
+ w
130
133
  ]);
131
- u(() => {
132
- if (!D) return;
134
+ f(() => {
135
+ if (!j) return;
133
136
  let e = [
134
137
  ...U.data ?? [],
135
138
  ...W.addresses,
136
139
  ...q
137
140
  ];
138
- De((t) => {
139
- let n = t.owner === D ? t.vas : [], r = new Set(n.map((e) => e.toLowerCase())), i = [...n], a = t.owner !== D;
141
+ Te((t) => {
142
+ let n = t.owner === j ? t.vas : [], r = new Set(n.map((e) => e.toLowerCase())), i = [...n], a = t.owner !== j;
140
143
  for (let t of e) {
141
- let e = p(t), n = e.toLowerCase();
144
+ let e = g(t), n = e.toLowerCase();
142
145
  r.has(n) || (r.add(n), i.push(e), a = !0);
143
146
  }
144
147
  return a ? {
145
- owner: D,
148
+ owner: j,
146
149
  vas: i
147
150
  } : t;
148
151
  });
149
152
  }, [
150
- D,
153
+ j,
151
154
  U.data,
152
155
  W.addresses,
153
156
  q
154
157
  ]);
155
- let Y = m({
158
+ let Y = _({
156
159
  queries: J.map((e) => {
157
- let t = ae(v, {
160
+ let t = ie(x, {
158
161
  partyA: e,
159
- chainId: y,
162
+ chainId: S,
160
163
  query: {
161
- enabled: E && S,
164
+ enabled: A && E,
162
165
  refetchInterval: B
163
166
  }
164
167
  });
@@ -180,13 +183,13 @@ function h(o) {
180
183
  error: e.find((e) => e.error)?.error ?? null,
181
184
  refetch: () => e.forEach((e) => e.refetch())
182
185
  })
183
- }), X = m({
186
+ }), X = _({
184
187
  queries: J.map((e) => {
185
- let t = oe(v, {
188
+ let t = oe(x, {
186
189
  partyA: e,
187
- chainId: y,
190
+ chainId: S,
188
191
  query: {
189
- enabled: E && C,
192
+ enabled: A && D,
190
193
  refetchInterval: B
191
194
  }
192
195
  });
@@ -208,13 +211,13 @@ function h(o) {
208
211
  error: e.find((e) => e.error)?.error ?? null,
209
212
  refetch: () => e.forEach((e) => e.refetch())
210
213
  })
211
- }), Z = m({
214
+ }), Z = _({
212
215
  queries: X.ids.map((e) => {
213
- let t = le(v, {
216
+ let t = le(x, {
214
217
  quoteId: e,
215
- chainId: y,
218
+ chainId: S,
216
219
  query: {
217
- enabled: E && C,
220
+ enabled: A && D,
218
221
  refetchInterval: B
219
222
  }
220
223
  });
@@ -235,26 +238,26 @@ function h(o) {
235
238
  isFetching: e.some((e) => e.isFetching),
236
239
  error: e.find((e) => e.error)?.error ?? null
237
240
  })
238
- }), Q = d(() => {
239
- if (!E || !h) return F.current = void 0, I.current = [], {
241
+ }), Q = p(() => {
242
+ if (!A || !v) return I.current = void 0, L.current = [], {
240
243
  quotes: [],
241
244
  links: {},
242
245
  pendingAnchors: []
243
246
  };
244
247
  let e = [...V.data ?? [], ...Object.values(R)], t = de({
245
- partyA: h,
246
- onchainPositions: S ? Y.quotes : [],
247
- onchainPendingQuotes: C ? Z.quotes : [],
248
- instantOpens: w ? e : [],
249
- instantCloses: T ? H.data ?? [] : [],
248
+ partyA: v,
249
+ onchainPositions: E ? Y.quotes : [],
250
+ onchainPendingQuotes: D ? Z.quotes : [],
251
+ instantOpens: O ? e : [],
252
+ instantCloses: k ? H.data ?? [] : [],
250
253
  instantOpenVaByTempId: W.byTempId,
251
254
  notifications: G,
252
- retainedAnchors: I.current
255
+ retainedAnchors: L.current
253
256
  });
254
- return F.current = t, I.current = t.pendingAnchors, t;
257
+ return I.current = t, L.current = t.pendingAnchors, t;
255
258
  }, [
256
- E,
257
- h,
259
+ A,
260
+ v,
258
261
  Y.quotes,
259
262
  Z.quotes,
260
263
  V.data,
@@ -262,38 +265,38 @@ function h(o) {
262
265
  W.byTempId,
263
266
  R,
264
267
  G,
265
- S,
266
- C,
267
- w,
268
- T
269
- ]), $ = d(() => {
268
+ E,
269
+ D,
270
+ O,
271
+ k
272
+ ]), $ = p(() => {
270
273
  let e = {};
271
274
  for (let t of Q.quotes) e[t.key] = t;
272
275
  return e;
273
276
  }, [Q.quotes]);
274
- u(() => {
277
+ f(() => {
275
278
  let e = Object.keys(R).map(Number).filter((e) => {
276
279
  let t = Q.links[e];
277
280
  return t !== void 0 && $[t]?.raw.onchain !== void 0;
278
281
  });
279
- e.length > 0 && ke(e);
282
+ e.length > 0 && Ae(e);
280
283
  }, [
281
284
  Q,
282
285
  $,
283
286
  R,
284
- ke
287
+ Ae
285
288
  ]);
286
- let Ve = E && b && U.isLoading || E && b && W.isLoading || E && S && Y.isLoading || E && C && (X.isLoading || Z.isLoading) || E && w && V.isLoading || E && T && H.isLoading, He = b && (U.isFetching || W.isFetching) || S && Y.isFetching || C && (X.isFetching || Z.isFetching) || w && V.isFetching || T && H.isFetching, Ue = Y.error ?? X.error ?? Z.error ?? U.error ?? V.error ?? H.error ?? null, We = Y.refetch, Ge = X.refetch, Ke = pe(() => {
287
- b && U.refetch(), S && We(), C && Ge(), w && V.refetch(), T && H.refetch();
289
+ let He = A && C && U.isLoading || A && C && W.isLoading || A && E && Y.isLoading || A && D && (X.isLoading || Z.isLoading) || A && O && V.isLoading || A && k && H.isLoading, Ue = C && (U.isFetching || W.isFetching) || E && Y.isFetching || D && (X.isFetching || Z.isFetching) || O && V.isFetching || k && H.isFetching, We = Y.error ?? X.error ?? Z.error ?? U.error ?? V.error ?? H.error ?? null, Ge = Y.refetch, Ke = X.refetch, qe = d(() => {
290
+ C && U.refetch(), E && Ge(), D && Ke(), O && V.refetch(), k && H.refetch();
288
291
  }, [
289
- b,
290
- S,
291
292
  C,
292
- w,
293
- T,
293
+ E,
294
+ D,
295
+ O,
296
+ k,
294
297
  U,
295
- We,
296
298
  Ge,
299
+ Ke,
297
300
  V,
298
301
  H
299
302
  ]);
@@ -301,14 +304,14 @@ function h(o) {
301
304
  quotes: Q.quotes,
302
305
  byKey: $,
303
306
  accounts: J,
304
- isLoading: !!Ve,
305
- isFetching: !!He,
306
- socketStatus: _ ? K : "closed",
307
- error: Ue,
308
- refetch: Ke
307
+ isLoading: !!He,
308
+ isFetching: !!Ue,
309
+ socketStatus: b ? K : "closed",
310
+ error: We,
311
+ refetch: qe
309
312
  };
310
313
  }
311
314
  //#endregion
312
- export { h as useManagedQuotes };
315
+ export { v as useManagedQuotes };
313
316
 
314
317
  //# sourceMappingURL=use-managed-quotes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-managed-quotes.js","names":[],"sources":["../../src/quotes/use-managed-quotes.ts"],"sourcesContent":["\"use client\";\n\nimport {\n classifyQuoteNotificationAction,\n getInstantClosesQueryKey,\n getInstantOpensQueryKey,\n getPartyAOpenPositionsQueryKey,\n getPartyAOpenPositionsQueryOptions,\n getPartyAPendingQuotesQueryKey,\n getPartyAPendingQuotesQueryOptions,\n getPredictedNextVirtualAccountQueryOptions,\n getQuoteQueryKey,\n getQuoteQueryOptions,\n isolationTypeForSide,\n QuoteLifecycle,\n reconcileQuotes,\n shouldAccelerateOnchainReads,\n type Notification,\n type Quote,\n type ReconcileQuotesResult,\n type SocketStatus,\n type UnifiedQuote,\n} from \"@symmio/trading-core\";\nimport { useQueries, useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getAddress, type Address } from \"viem\";\nimport { useVirtualAccountsAddressesOfSubAccount } from \"../account-layer/use-virtual-accounts-addresses-of-sub-account\";\nimport { normalizeSymmError } from \"../errors/normalize-symm-error\";\nimport type { SymmioRequestError } from \"../errors/symmio-request-error\";\nimport { useInstantCloses } from \"../instant-layer/use-instant-closes\";\nimport { useInstantOpens } from \"../instant-layer/use-instant-opens\";\nimport { useSymmioChainId } from \"../provider/use-symmio-chain-id\";\nimport { useSymmioConfig } from \"../provider/use-symmio-config\";\nimport { predicateMatch } from \"../utils\";\nimport { useNotifications } from \"../websocket/use-notifications\";\nimport { useOptimisticQuotesStore } from \"./optimistic-quotes-store\";\n\n/**\n * Baseline poll interval (ms) used **only as a fallback** when the live event channel\n * is unavailable (`live` is off, or the notifications socket is not `open`). With the\n * socket up the feature is events-first: there is no idle on-chain poll unless the\n * consumer opts into one via `pollingInterval`.\n */\nconst FALLBACK_POLLING_INTERVAL = 5_000;\n\n/** Accelerated quote-polling interval (ms) while a row is mid-transition. */\nconst ACCELERATED_POLLING_INTERVAL = 1_500;\n\n/**\n * Cap on the live-notification buffer fed back into the merge. Reconciliation is\n * idempotent over already-applied notifications, so only a recent window is kept\n * to bound memory and reprocessing.\n *\n * TODO: check this and packages/trading-react/src/quotes/use-managed-quotes.ts#L188-L206\n */\nconst NOTIFICATION_BUFFER_LIMIT = 100;\n\n/** Stable empty array so the `accounts` memo doesn't churn while no VAs are retained. */\nconst NO_RETAINED_VAS: readonly Address[] = [];\n\n/** Debounce (ms) for coalescing a burst of notifications into one set of read invalidations. */\nconst NOTIFICATION_INVALIDATE_DEBOUNCE = 250;\n\n/**\n * Lifecycle stages that mean an open is in flight, so the hedger instant-opens\n * feed is worth polling. Outside these stages the feed has nothing new (a\n * settled position is tracked by the on-chain reads), so polling it is wasted.\n */\nconst OPEN_INTENT_LIFECYCLES = new Set<QuoteLifecycle>([\n QuoteLifecycle.OPTIMISTIC,\n QuoteLifecycle.PRICE_FILLED,\n QuoteLifecycle.WRITE_ONCHAIN,\n]);\n\n/**\n * Lifecycle stages that mean a close is in flight, so the hedger instant-closes\n * feed is worth polling. Outside these stages there is no pending close, so\n * polling the feed (merely holding open positions) is wasted.\n */\nconst CLOSE_INTENT_LIFECYCLES = new Set<QuoteLifecycle>([QuoteLifecycle.WRITE_ONCHAIN_CLOSE, QuoteLifecycle.CLOSING]);\n\n/**\n * Which underlying quote sources {@link useManagedQuotes} should read. Every\n * source defaults to `true`; set one to `false` to skip its query/subscription\n * entirely (e.g. a screen that never opens instant trades).\n */\nexport interface ManagedQuotesSources {\n /** Read on-chain open positions via `usePartyAOpenPositions`. Default `true`. */\n openPositions?: boolean;\n /** Read on-chain pending quote ids (hydrated per-id) via `usePartyAPendingQuotes`. Default `true`. */\n pendingQuotes?: boolean;\n /** Read pending instant-opens from the hedger via `useInstantOpens`. Default `true`. */\n instantOpens?: boolean;\n /** Read pending instant-closes from the hedger via `useInstantCloses`. Default `true`. */\n instantCloses?: boolean;\n}\n\n/**\n * Parameters for {@link useManagedQuotes}.\n */\nexport interface UseManagedQuotesParameters {\n /** Sub-account (partyA) to manage quotes for. The hook is idle until this is set. */\n partyA?: Address;\n /** Target chain id. Defaults to the connected chain. */\n chainId?: number;\n /**\n * Opt-in idle polling cadence (ms). **Default off** — with `live` notifications the\n * feature is events-first: it does not poll at idle, only (a) accelerates on-chain\n * reads briefly while a row awaits on-chain confirmation (the RPC-lag retry), and\n * (b) falls back to a baseline poll when the event channel is down. Set this to make\n * it poll on a fixed cadence regardless (e.g. a live-inspector panel).\n */\n pollingInterval?: number;\n /** Subscribe to the live notifications stream. Default `true`; set `false` for poll-only. */\n live?: boolean;\n /** Master switch. When `false` every source is idle regardless of `sources`. Default `true`. */\n enabled?: boolean;\n /**\n * Union the sub-account's existing on-chain Virtual Accounts (VAs) — plus the\n * predicted VAs of its pending instant-opens and any VAs seen on the\n * notifications stream — into the on-chain reads. In lowcap each isolated\n * position lives under a VA, so this is required to see the full picture.\n * Default `true`.\n */\n includeVirtualAccounts?: boolean;\n /** Extra accounts to read quotes across (e.g. VAs already known to the consumer). */\n extraAccounts?: readonly Address[];\n /** Per-source toggles; omit to read every source. */\n sources?: ManagedQuotesSources;\n}\n\n/**\n * Value returned by {@link useManagedQuotes}.\n */\nexport interface UseManagedQuotesResult {\n /** Merged, de-duplicated, lifecycle-tagged rows, newest first. */\n quotes: UnifiedQuote[];\n /** The same rows indexed by their stable {@link UnifiedQuote.key}. */\n byKey: Record<string, UnifiedQuote>;\n /** The on-chain `partyA` accounts the quotes were read across (sub-account + VAs + predicted + extras). */\n accounts: Address[];\n /** `true` while any enabled source has not produced its first result. */\n isLoading: boolean;\n /** `true` while any enabled source is fetching (background refetch included). */\n isFetching: boolean;\n /** Live connection status of the notifications socket (`\"closed\"` when `live` is off). */\n socketStatus: SocketStatus;\n /** The first error surfaced by any source, normalized, or `null`. */\n error: SymmioRequestError | null;\n /** Force every enabled source to refetch immediately. */\n refetch: () => void;\n}\n\n/**\n * Orchestrate every quote source for one sub-account — fanned out across every\n * account that holds its positions — into a single, stable, lifecycle-tagged\n * table.\n *\n * In lowcap, isolated positions live under Virtual Accounts (VAs), so a\n * sub-account's quotes are spread across its VAs rather than the sub-account\n * itself. This resolves the full account set — the sub-account, its existing\n * VAs (`useVirtualAccountsAddressesOfSubAccount`), the predicted VAs of its\n * pending instant-opens (`getPredictedNextVirtualAccount`), VAs seen on the\n * notifications stream, and any `extraAccounts` — then reads\n * `getPartyAOpenPositions` and `getPartyAPendingQuotes` (+ per-id `getQuote`\n * hydration) across that set via `useQueries`. Off-chain hedger reads\n * (`useInstantOpens` / `useInstantCloses`) stay scoped to the sub-account.\n *\n * Every source is gated by `sources`, `enabled`, and a set `partyA`, then their\n * snapshots flow through the pure core `reconcileQuotes` (\"active quotes only\" —\n * a quote shows iff it is in a source this tick), stamping each optimistic\n * instant-open with its predicted VA via `instantOpenVaByTempId`. Live\n * notifications (via `useNotifications`, unless `live` is `false`) are applied in\n * the same merge. With `live` notifications the feature is **events-first**: it does\n * not poll at idle, only accelerating the on-chain reads briefly while a row awaits\n * on-chain confirmation (`shouldAccelerateOnchainReads`, the RPC-lag retry), and\n * falling back to a baseline poll only when the event channel is down.\n *\n * Optimistic instant-opens seeded into {@link useOptimisticQuotesStore} are\n * merged in as extra `instantOpens` so a just-submitted trade shows instantly,\n * then cleared once the same `tempQuoteId` lands on-chain.\n *\n * @example\n * ```tsx\n * const { quotes, accounts, socketStatus, isLoading } = useManagedQuotes({ partyA });\n * ```\n */\nexport function useManagedQuotes(parameters: UseManagedQuotesParameters): UseManagedQuotesResult {\n const { partyA, chainId, pollingInterval, live = true, enabled = true } = parameters;\n const config = useSymmioConfig();\n const defaultChainId = useSymmioChainId();\n const resolvedChainId = chainId ?? defaultChainId;\n const includeVirtualAccounts = parameters.includeVirtualAccounts ?? true;\n const extraAccounts = parameters.extraAccounts;\n const sources = parameters.sources;\n const wantOpenPositions = sources?.openPositions ?? true;\n const wantPendingQuotes = sources?.pendingQuotes ?? true;\n const wantInstantOpens = sources?.instantOpens ?? true;\n const wantInstantCloses = sources?.instantCloses ?? true;\n const active = enabled && Boolean(partyA);\n\n /**\n * Identity of the current account set's owner. VA retention (below) is scoped\n * to this `(chainId, partyA)` so switching sub-accounts never carries another\n * account's VAs into the read set.\n */\n const retentionOwner = active && partyA ? `${resolvedChainId}:${partyA.toLowerCase()}` : undefined;\n\n /**\n * VAs retained across the optimistic→on-chain hand-off. A predicted VA leaves\n * `predictedVas` the instant its instant-open lands on-chain (the hedger drops\n * the pending open), while `getVirtualAccountsAddressesOfSubAccount` and the\n * notification `va_address` can lag a poll behind — so without retention we'd\n * stop polling the exact VA the position just landed in, and the row would\n * vanish for a tick before reappearing as its `ONCHAIN` twin. VAs are\n * append-only on-chain, so once discovered we keep reading them while the owner\n * is unchanged. See reference-va-address-resolution in agent memory.\n */\n const [retained, setRetained] = useState<{ owner?: string; vas: Address[] }>({ vas: [] });\n const retainedVas = retained.owner === retentionOwner ? retained.vas : NO_RETAINED_VAS;\n\n /**\n * Notification-driven invalidation. Reads are kept in sync off the live\n * notifications stream — not polling — so the feature works with polling off.\n * `queryClient` and the cache scope (`configKey`) are mirrored into refs so the\n * `onNotification` callback below can stay referentially stable (a new callback\n * identity would resubscribe the socket). The debounce timer coalesces a burst\n * of notifications into one invalidation pass.\n */\n const queryClient = useQueryClient();\n const queryClientRef = useRef(queryClient);\n queryClientRef.current = queryClient;\n const configKey = config.getChainConfigKey(resolvedChainId);\n const configKeyRef = useRef(configKey);\n configKeyRef.current = configKey;\n const invalidateTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n /**\n * Which hedger feeds a debounced notification burst should invalidate. A burst\n * can mix open and close events, so the kinds are accumulated here across the\n * debounce window and read (then reset) when the timer fires — scoping the\n * invalidation to the feeds the events can actually affect.\n */\n const pendingInvalidationRef = useRef<{ opens: boolean; closes: boolean }>({ opens: false, closes: false });\n\n /**\n * Last reconciliation result, kept in a ref so it survives renders without\n * triggering one. Its only remaining job is to feed\n * {@link shouldAccelerateOnchainReads} (and the feed-intent gates) the previous\n * tick's result, since the source queries set their `refetchInterval` before this\n * render's result exists. (\"Active quotes only\" dropped the grace window, and\n * `links` are recomputed fresh on each merge.)\n */\n const previousRef = useRef<ReconcileQuotesResult | undefined>(undefined);\n\n /**\n * Rows anchored on a prior tick (a notification set their `quoteId`) but not yet\n * returned by the on-chain read — the previous merge's `pendingAnchors`. Fed back\n * into {@link reconcileQuotes} so an anchored row keeps showing while the RPC\n * catches up, instead of vanishing once the hedger drops its pending open. Held in\n * a ref so it survives renders without triggering one; the source query that\n * dropped the row drives the recompute that reads it.\n */\n const retainedAnchorsRef = useRef<UnifiedQuote[]>([]);\n\n /**\n * Last tick's socket status, read one render behind (like `previousRef`) to decide\n * whether the live event channel is up. Updated right after `useNotifications` below.\n * When the channel is live the feature is events-first (no idle poll); when it is\n * down we fall back to polling so state still advances without notifications.\n */\n const socketStatusRef = useRef<SocketStatus>(\"closed\");\n\n const optimisticEntries = useOptimisticQuotesStore((state) => state.entries);\n const clearSettled = useOptimisticQuotesStore((state) => state.clearSettled);\n\n /** Live event channel = subscribed (`live`) and the socket was `open` last render. */\n const eventChannelLive = live && socketStatusRef.current === \"open\";\n /** Consumer's opt-in idle cadence (off by default). */\n const idleInterval = pollingInterval && pollingInterval > 0 ? pollingInterval : false;\n\n /**\n * On-chain reads accelerate to {@link ACCELERATED_POLLING_INTERVAL} **only** while a\n * row awaits on-chain confirmation (`WRITE_ONCHAIN` / `WRITE_ONCHAIN_CLOSE` /\n * `CLOSING`) — the RPC-lag retry. Otherwise: no idle poll when the event channel is\n * live (events drive updates) unless the consumer opted into `idleInterval`; a\n * baseline fallback when the channel is down so state still progresses. Read from the\n * previous result because the queries set their interval before this render's result\n * exists (an on-chain poll / notification re-render advances it a tick later).\n */\n const accelerateOnchain = previousRef.current ? shouldAccelerateOnchainReads(previousRef.current) : false;\n const onchainIdleInterval = eventChannelLive ? idleInterval : idleInterval || FALLBACK_POLLING_INTERVAL;\n const refetchInterval = active ? (accelerateOnchain ? ACCELERATED_POLLING_INTERVAL : onchainIdleInterval) : false;\n\n /**\n * Hedger feeds are event-driven while the channel is live: the open/close mutation\n * invalidates the matching feed once and the notifications advance the stage, so they\n * do not poll (unless the consumer opted into `idleInterval`). When the channel is\n * down they poll while the matching flow is in flight, to track it without\n * notifications. `hasOpenIntent` / `hasCloseIntent` come from the previous tick.\n */\n const previousQuotes = previousRef.current?.quotes;\n const hasOpenIntent = previousQuotes?.some((quote) => OPEN_INTENT_LIFECYCLES.has(quote.lifecycle)) ?? false;\n const hasCloseIntent = previousQuotes?.some((quote) => CLOSE_INTENT_LIFECYCLES.has(quote.lifecycle)) ?? false;\n const feedInterval = (hasIntent: boolean) =>\n !eventChannelLive && hasIntent ? ACCELERATED_POLLING_INTERVAL : idleInterval;\n const instantOpensInterval = active && wantInstantOpens ? feedInterval(hasOpenIntent) : false;\n const instantClosesInterval = active && wantInstantCloses ? feedInterval(hasCloseIntent) : false;\n\n /**\n * Off-chain hedger reads — always scoped to the sub-account, never the VAs. Kept\n * `enabled` so a mutation's `onSuccess` invalidation can fetch them on demand, but\n * polled only while the matching flow is in flight (see the interval gates above).\n */\n const instantOpens = useInstantOpens({\n partyA: partyA as Address,\n chainId: resolvedChainId,\n query: { enabled: active && wantInstantOpens, refetchInterval: instantOpensInterval },\n });\n\n const instantCloses = useInstantCloses({\n partyA: partyA as Address,\n chainId: resolvedChainId,\n query: { enabled: active && wantInstantCloses, refetchInterval: instantClosesInterval },\n });\n\n /** The sub-account's existing on-chain VAs. Empty (harmless) when `partyA` is itself a VA. */\n const virtualAccounts = useVirtualAccountsAddressesOfSubAccount({\n subAccount: partyA,\n chainId: resolvedChainId,\n query: { enabled: active && includeVirtualAccounts, refetchInterval },\n });\n\n /**\n * Brand-new-VA bridge: a position can open in a market the sub-account has\n * never traded, landing in a freshly created VA that is not yet in\n * `getVirtualAccountsAddressesOfSubAccount`. The predicted VA below covers it\n * while the instant-open is pending; once it lands on-chain the hedger drops the\n * open and the prediction with it, so VA retention (`retained`, above) keeps the\n * VA in the poll set across the hand-off — the row transitions to `ONCHAIN` in\n * place instead of flickering out and back.\n */\n\n /**\n * Predict the VA each pending instant-open will land in. The set of opens is\n * dynamic, but `useQueries` over a dynamic array is allowed — the hook count\n * stays one regardless of length.\n */\n const pendingOpens = wantInstantOpens ? (instantOpens.data ?? []) : [];\n const predictedVas = useQueries({\n queries: pendingOpens.map((open) => ({\n ...getPredictedNextVirtualAccountQueryOptions(config, {\n subAccount: partyA,\n chainId: resolvedChainId,\n isolationType: isolationTypeForSide(open.positionType),\n symbolId: BigInt(open.marketId),\n query: { enabled: active && includeVirtualAccounts, refetchInterval },\n }),\n })),\n combine: (results) => ({\n byTempId: pendingOpens.reduce<Record<number, Address>>((map, open, index) => {\n const predicted = results[index]?.data;\n if (predicted) map[open.tempQuoteId] = getAddress(predicted);\n return map;\n }, {}),\n addresses: results.map((result) => result.data).filter((address): address is Address => Boolean(address)),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n }),\n });\n\n const [notifications, setNotifications] = useState<Notification[]>([]);\n const { status: socketStatus } = useNotifications({\n account: partyA,\n chainId: resolvedChainId,\n enabled: active && live,\n onNotification: useCallback((notification: Notification) => {\n setNotifications((prev) => [...prev, notification].slice(-NOTIFICATION_BUFFER_LIMIT));\n /**\n * Refetch the authoritative reads off the live event so both tables stay in\n * sync without polling. The on-chain reads always refresh (any lifecycle event\n * can change them); the hedger feeds refresh only for the matching flow, so an\n * open event never re-fetches the closes feed and vice versa. Kinds are\n * accumulated across the debounce window because a burst can mix open and close\n * events. Scoped to this chain (`configKey`); React Query dedups concurrent\n * refetches of the same query.\n */\n const kind = classifyQuoteNotificationAction(notification.lastSeenAction);\n const pending = pendingInvalidationRef.current;\n if (kind === \"open\") pending.opens = true;\n else if (kind === \"close\") pending.closes = true;\n else {\n pending.opens = true;\n pending.closes = true;\n }\n if (invalidateTimerRef.current) clearTimeout(invalidateTimerRef.current);\n invalidateTimerRef.current = setTimeout(() => {\n const client = queryClientRef.current;\n const scope = { configKey: configKeyRef.current };\n const { opens, closes } = pendingInvalidationRef.current;\n pendingInvalidationRef.current = { opens: false, closes: false };\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAOpenPositionsQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAPendingQuotesQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getQuoteQueryKey, scope) });\n if (opens) void client.invalidateQueries({ predicate: predicateMatch(getInstantOpensQueryKey, scope) });\n if (closes) void client.invalidateQueries({ predicate: predicateMatch(getInstantClosesQueryKey, scope) });\n }, NOTIFICATION_INVALIDATE_DEBOUNCE);\n }, []),\n });\n\n /** Mirror the live socket status into the ref the interval gating reads next render. */\n socketStatusRef.current = socketStatus;\n\n /**\n * One-shot re-sync when the notifications socket **reconnects**. The stream does not\n * replay messages missed while it was down, so on a re-`open` we invalidate the reads\n * once to catch up — this replaces a continuous fallback poll. The first connect is\n * skipped (the queries already fetched on mount).\n */\n const hasBeenOpenRef = useRef(false);\n useEffect(() => {\n if (!live || socketStatus !== \"open\") return;\n if (hasBeenOpenRef.current) {\n const client = queryClientRef.current;\n const scope = { configKey: configKeyRef.current };\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAOpenPositionsQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAPendingQuotesQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getQuoteQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getInstantOpensQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getInstantClosesQueryKey, scope) });\n }\n hasBeenOpenRef.current = true;\n }, [socketStatus, live]);\n\n /** Clear the pending invalidation timer on unmount. */\n useEffect(() => {\n return () => {\n if (invalidateTimerRef.current) clearTimeout(invalidateTimerRef.current);\n };\n }, []);\n\n /** Distinct VA addresses seen on the notifications stream. */\n const notificationVas = useMemo<Address[]>(() => {\n const seen = new Set<string>();\n const result: Address[] = [];\n for (const notification of notifications) {\n if (!notification.vaAddress) continue;\n const checksummed = getAddress(notification.vaAddress);\n const lower = checksummed.toLowerCase();\n if (seen.has(lower)) continue;\n seen.add(lower);\n result.push(checksummed);\n }\n return result;\n }, [notifications]);\n\n /**\n * The deduplicated (case-insensitive), checksummed set of on-chain accounts to\n * read quotes across — the sub-account, its VAs, the predicted VAs, the\n * notification VAs, and any extras. Order: sub-account first, then the rest.\n */\n const accounts = useMemo<Address[]>(() => {\n if (!active || !partyA) return [];\n const seen = new Set<string>();\n const result: Address[] = [];\n const add = (address: Address) => {\n const checksummed = getAddress(address);\n const lower = checksummed.toLowerCase();\n if (seen.has(lower)) return;\n seen.add(lower);\n result.push(checksummed);\n };\n add(partyA);\n if (includeVirtualAccounts) {\n for (const virtualAccount of virtualAccounts.data ?? []) add(virtualAccount);\n for (const predicted of predictedVas.addresses) add(predicted);\n for (const notificationVa of notificationVas) add(notificationVa);\n for (const retainedVa of retainedVas) add(retainedVa);\n }\n for (const extra of extraAccounts ?? []) add(extra);\n return result;\n }, [\n active,\n partyA,\n includeVirtualAccounts,\n virtualAccounts.data,\n predictedVas.addresses,\n notificationVas,\n retainedVas,\n extraAccounts,\n ]);\n\n /**\n * Accumulate every VA we discover (list + predicted + notification) into the\n * retained set so none ever leaves the poll set mid-hand-off. Monotonic per\n * owner; resets when the owner `(chainId, partyA)` changes. Setting state only\n * when something new appears keeps this from looping.\n */\n useEffect(() => {\n if (!retentionOwner) return;\n const discovered = [...(virtualAccounts.data ?? []), ...predictedVas.addresses, ...notificationVas];\n setRetained((prev) => {\n const carryOver = prev.owner === retentionOwner ? prev.vas : [];\n const seen = new Set(carryOver.map((address) => address.toLowerCase()));\n const next = [...carryOver];\n let changed = prev.owner !== retentionOwner;\n for (const va of discovered) {\n const checksummed = getAddress(va);\n const lower = checksummed.toLowerCase();\n if (seen.has(lower)) continue;\n seen.add(lower);\n next.push(checksummed);\n changed = true;\n }\n return changed ? { owner: retentionOwner, vas: next } : prev;\n });\n }, [retentionOwner, virtualAccounts.data, predictedVas.addresses, notificationVas]);\n\n /** On-chain open positions, fanned out across every account, flattened to one `Quote[]`. */\n const openPositions = useQueries({\n queries: accounts.map((account) => {\n const options = getPartyAOpenPositionsQueryOptions(config, {\n partyA: account,\n chainId: resolvedChainId,\n query: { enabled: active && wantOpenPositions, refetchInterval },\n });\n return {\n ...options,\n queryFn: async () => {\n try {\n return await options.queryFn();\n } catch (err) {\n throw normalizeSymmError(err);\n }\n },\n };\n }),\n combine: (results) => ({\n quotes: results.flatMap((result) => result.data ?? []),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n error: (results.find((result) => result.error)?.error as SymmioRequestError | undefined) ?? null,\n refetch: () => results.forEach((result) => result.refetch()),\n }),\n });\n /** Pending quote ids, fanned out across every account, then hydrated per id. */\n const pendingQuoteIds = useQueries({\n queries: accounts.map((account) => {\n const options = getPartyAPendingQuotesQueryOptions(config, {\n partyA: account,\n chainId: resolvedChainId,\n query: { enabled: active && wantPendingQuotes, refetchInterval },\n });\n return {\n ...options,\n queryFn: async () => {\n try {\n return await options.queryFn();\n } catch (err) {\n throw normalizeSymmError(err);\n }\n },\n };\n }),\n combine: (results) => ({\n ids: results.flatMap((result) => result.data ?? []),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n error: (results.find((result) => result.error)?.error as SymmioRequestError | undefined) ?? null,\n refetch: () => results.forEach((result) => result.refetch()),\n }),\n });\n\n const hydratedPending = useQueries({\n queries: pendingQuoteIds.ids.map((quoteId) => {\n const options = getQuoteQueryOptions(config, {\n quoteId,\n chainId: resolvedChainId,\n query: { enabled: active && wantPendingQuotes, refetchInterval },\n });\n return {\n ...options,\n queryFn: async () => {\n try {\n return await options.queryFn();\n } catch (err) {\n throw normalizeSymmError(err);\n }\n },\n };\n }),\n combine: (results) => ({\n quotes: results.map((result) => result.data).filter((quote): quote is Quote => Boolean(quote)),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n error: (results.find((result) => result.error)?.error as SymmioRequestError | undefined) ?? null,\n }),\n });\n\n const result = useMemo<ReconcileQuotesResult>(() => {\n if (!active || !partyA) {\n previousRef.current = undefined;\n retainedAnchorsRef.current = [];\n return { quotes: [], links: {}, pendingAnchors: [] };\n }\n const seededInstantOpens = [...(instantOpens.data ?? []), ...Object.values(optimisticEntries)];\n const next = reconcileQuotes({\n partyA,\n onchainPositions: wantOpenPositions ? openPositions.quotes : [],\n onchainPendingQuotes: wantPendingQuotes ? hydratedPending.quotes : [],\n instantOpens: wantInstantOpens ? seededInstantOpens : [],\n instantCloses: wantInstantCloses ? (instantCloses.data ?? []) : [],\n instantOpenVaByTempId: predictedVas.byTempId,\n notifications,\n retainedAnchors: retainedAnchorsRef.current,\n });\n previousRef.current = next;\n retainedAnchorsRef.current = next.pendingAnchors;\n return next;\n }, [\n active,\n partyA,\n openPositions.quotes,\n hydratedPending.quotes,\n instantOpens.data,\n instantCloses.data,\n predictedVas.byTempId,\n optimisticEntries,\n notifications,\n wantOpenPositions,\n wantPendingQuotes,\n wantInstantOpens,\n wantInstantCloses,\n ]);\n\n const byKey = useMemo<Record<string, UnifiedQuote>>(() => {\n const map: Record<string, UnifiedQuote> = {};\n for (const quote of result.quotes) map[quote.key] = quote;\n return map;\n }, [result.quotes]);\n\n /**\n * Drop optimistic seeds once their `tempQuoteId` has been **confirmed by the\n * on-chain read** — the linked row carries the polled struct (`raw.onchain`).\n * Clearing on the notification link alone would drop the seed while the row is\n * still `WRITE_ONCHAIN`, before any source but the notification holds it, so the\n * row would flicker out until the RPC catches up.\n */\n useEffect(() => {\n const settled = Object.keys(optimisticEntries)\n .map(Number)\n .filter((tempQuoteId) => {\n const key = result.links[tempQuoteId];\n return key !== undefined && byKey[key]?.raw.onchain !== undefined;\n });\n if (settled.length > 0) clearSettled(settled);\n }, [result, byKey, optimisticEntries, clearSettled]);\n\n const isLoading =\n (active && includeVirtualAccounts && virtualAccounts.isLoading) ||\n (active && includeVirtualAccounts && predictedVas.isLoading) ||\n (active && wantOpenPositions && openPositions.isLoading) ||\n (active && wantPendingQuotes && (pendingQuoteIds.isLoading || hydratedPending.isLoading)) ||\n (active && wantInstantOpens && instantOpens.isLoading) ||\n (active && wantInstantCloses && instantCloses.isLoading);\n\n const isFetching =\n (includeVirtualAccounts && (virtualAccounts.isFetching || predictedVas.isFetching)) ||\n (wantOpenPositions && openPositions.isFetching) ||\n (wantPendingQuotes && (pendingQuoteIds.isFetching || hydratedPending.isFetching)) ||\n (wantInstantOpens && instantOpens.isFetching) ||\n (wantInstantCloses && instantCloses.isFetching);\n\n const error =\n openPositions.error ??\n pendingQuoteIds.error ??\n hydratedPending.error ??\n virtualAccounts.error ??\n instantOpens.error ??\n instantCloses.error ??\n null;\n\n /**\n * `openPositions` / `pendingQuoteIds` are `useQueries` fan-outs (no single\n * query handle), so their combined results expose a `refetch` that fires every\n * per-account query. Refetching the ids re-drives the per-id hydration.\n */\n const refetchOpenPositions = openPositions.refetch;\n const refetchPendingQuoteIds = pendingQuoteIds.refetch;\n const refetch = useCallback(() => {\n if (includeVirtualAccounts) virtualAccounts.refetch();\n if (wantOpenPositions) refetchOpenPositions();\n if (wantPendingQuotes) refetchPendingQuoteIds();\n if (wantInstantOpens) instantOpens.refetch();\n if (wantInstantCloses) instantCloses.refetch();\n }, [\n includeVirtualAccounts,\n wantOpenPositions,\n wantPendingQuotes,\n wantInstantOpens,\n wantInstantCloses,\n virtualAccounts,\n refetchOpenPositions,\n refetchPendingQuoteIds,\n instantOpens,\n instantCloses,\n ]);\n\n return {\n quotes: result.quotes,\n byKey,\n accounts,\n isLoading: Boolean(isLoading),\n isFetching: Boolean(isFetching),\n socketStatus: live ? socketStatus : \"closed\",\n error,\n refetch,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-managed-quotes.js","names":[],"sources":["../../src/quotes/use-managed-quotes.ts"],"sourcesContent":["\"use client\";\n\nimport {\n classifyQuoteNotificationAction,\n getInstantClosesQueryKey,\n getInstantOpensQueryKey,\n getPartyAOpenPositionsQueryKey,\n getPartyAOpenPositionsQueryOptions,\n getPartyAPendingQuotesQueryKey,\n getPartyAPendingQuotesQueryOptions,\n getPredictedNextVirtualAccountQueryOptions,\n getQuoteQueryKey,\n getQuoteQueryOptions,\n isolationTypeForSide,\n QuoteLifecycle,\n reconcileQuotes,\n shouldAccelerateOnchainReads,\n type Notification,\n type Quote,\n type ReconcileQuotesResult,\n type SocketStatus,\n type UnifiedQuote,\n} from \"@symmio/trading-core\";\nimport { useQueries, useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { getAddress, type Address } from \"viem\";\nimport { useVirtualAccountsAddressesOfSubAccount } from \"../account-layer/use-virtual-accounts-addresses-of-sub-account\";\nimport { normalizeSymmError } from \"../errors/normalize-symm-error\";\nimport type { SymmioRequestError } from \"../errors/symmio-request-error\";\nimport { useInstantCloses } from \"../instant-layer/use-instant-closes\";\nimport { useInstantOpens } from \"../instant-layer/use-instant-opens\";\nimport { useSymmioChainId } from \"../provider/use-symmio-chain-id\";\nimport { useSymmioConfig } from \"../provider/use-symmio-config\";\nimport { useTpSlStore } from \"../tpsl/tpsl-store\";\nimport { predicateMatch } from \"../utils\";\nimport { useNotifications } from \"../websocket/use-notifications\";\nimport { useOptimisticQuotesStore } from \"./optimistic-quotes-store\";\n\n/**\n * Baseline poll interval (ms) used **only as a fallback** when the live event channel\n * is unavailable (`live` is off, or the notifications socket is not `open`). With the\n * socket up the feature is events-first: there is no idle on-chain poll unless the\n * consumer opts into one via `pollingInterval`.\n */\nconst FALLBACK_POLLING_INTERVAL = 5_000;\n\n/** Accelerated quote-polling interval (ms) while a row is mid-transition. */\nconst ACCELERATED_POLLING_INTERVAL = 1_500;\n\n/**\n * Cap on the live-notification buffer fed back into the merge. Reconciliation is\n * idempotent over already-applied notifications, so only a recent window is kept\n * to bound memory and reprocessing.\n *\n * TODO: check this and packages/trading-react/src/quotes/use-managed-quotes.ts#L188-L206\n */\nconst NOTIFICATION_BUFFER_LIMIT = 100;\n\n/** Stable empty array so the `accounts` memo doesn't churn while no VAs are retained. */\nconst NO_RETAINED_VAS: readonly Address[] = [];\n\n/** Debounce (ms) for coalescing a burst of notifications into one set of read invalidations. */\nconst NOTIFICATION_INVALIDATE_DEBOUNCE = 250;\n\n/**\n * Lifecycle stages that mean an open is in flight, so the hedger instant-opens\n * feed is worth polling. Outside these stages the feed has nothing new (a\n * settled position is tracked by the on-chain reads), so polling it is wasted.\n */\nconst OPEN_INTENT_LIFECYCLES = new Set<QuoteLifecycle>([\n QuoteLifecycle.OPTIMISTIC,\n QuoteLifecycle.PRICE_FILLED,\n QuoteLifecycle.WRITE_ONCHAIN,\n]);\n\n/**\n * Lifecycle stages that mean a close is in flight, so the hedger instant-closes\n * feed is worth polling. Outside these stages there is no pending close, so\n * polling the feed (merely holding open positions) is wasted.\n */\nconst CLOSE_INTENT_LIFECYCLES = new Set<QuoteLifecycle>([QuoteLifecycle.WRITE_ONCHAIN_CLOSE, QuoteLifecycle.CLOSING]);\n\n/**\n * Which underlying quote sources {@link useManagedQuotes} should read. Every\n * source defaults to `true`; set one to `false` to skip its query/subscription\n * entirely (e.g. a screen that never opens instant trades).\n */\nexport interface ManagedQuotesSources {\n /** Read on-chain open positions via `usePartyAOpenPositions`. Default `true`. */\n openPositions?: boolean;\n /** Read on-chain pending quote ids (hydrated per-id) via `usePartyAPendingQuotes`. Default `true`. */\n pendingQuotes?: boolean;\n /** Read pending instant-opens from the hedger via `useInstantOpens`. Default `true`. */\n instantOpens?: boolean;\n /** Read pending instant-closes from the hedger via `useInstantCloses`. Default `true`. */\n instantCloses?: boolean;\n}\n\n/**\n * Parameters for {@link useManagedQuotes}.\n */\nexport interface UseManagedQuotesParameters {\n /** Sub-account (partyA) to manage quotes for. The hook is idle until this is set. */\n partyA?: Address;\n /** Target chain id. Defaults to the connected chain. */\n chainId?: number;\n /**\n * Opt-in idle polling cadence (ms). **Default off** — with `live` notifications the\n * feature is events-first: it does not poll at idle, only (a) accelerates on-chain\n * reads briefly while a row awaits on-chain confirmation (the RPC-lag retry), and\n * (b) falls back to a baseline poll when the event channel is down. Set this to make\n * it poll on a fixed cadence regardless (e.g. a live-inspector panel).\n */\n pollingInterval?: number;\n /** Subscribe to the live notifications stream. Default `true`; set `false` for poll-only. */\n live?: boolean;\n /** Master switch. When `false` every source is idle regardless of `sources`. Default `true`. */\n enabled?: boolean;\n /**\n * Union the sub-account's existing on-chain Virtual Accounts (VAs) — plus the\n * predicted VAs of its pending instant-opens and any VAs seen on the\n * notifications stream — into the on-chain reads. In lowcap each isolated\n * position lives under a VA, so this is required to see the full picture.\n * Default `true`.\n */\n includeVirtualAccounts?: boolean;\n /** Extra accounts to read quotes across (e.g. VAs already known to the consumer). */\n extraAccounts?: readonly Address[];\n /** Per-source toggles; omit to read every source. */\n sources?: ManagedQuotesSources;\n}\n\n/**\n * Value returned by {@link useManagedQuotes}.\n */\nexport interface UseManagedQuotesResult {\n /** Merged, de-duplicated, lifecycle-tagged rows, newest first. */\n quotes: UnifiedQuote[];\n /** The same rows indexed by their stable {@link UnifiedQuote.key}. */\n byKey: Record<string, UnifiedQuote>;\n /** The on-chain `partyA` accounts the quotes were read across (sub-account + VAs + predicted + extras). */\n accounts: Address[];\n /** `true` while any enabled source has not produced its first result. */\n isLoading: boolean;\n /** `true` while any enabled source is fetching (background refetch included). */\n isFetching: boolean;\n /** Live connection status of the notifications socket (`\"closed\"` when `live` is off). */\n socketStatus: SocketStatus;\n /** The first error surfaced by any source, normalized, or `null`. */\n error: SymmioRequestError | null;\n /** Force every enabled source to refetch immediately. */\n refetch: () => void;\n}\n\n/**\n * Orchestrate every quote source for one sub-account — fanned out across every\n * account that holds its positions — into a single, stable, lifecycle-tagged\n * table.\n *\n * In lowcap, isolated positions live under Virtual Accounts (VAs), so a\n * sub-account's quotes are spread across its VAs rather than the sub-account\n * itself. This resolves the full account set — the sub-account, its existing\n * VAs (`useVirtualAccountsAddressesOfSubAccount`), the predicted VAs of its\n * pending instant-opens (`getPredictedNextVirtualAccount`), VAs seen on the\n * notifications stream, and any `extraAccounts` — then reads\n * `getPartyAOpenPositions` and `getPartyAPendingQuotes` (+ per-id `getQuote`\n * hydration) across that set via `useQueries`. Off-chain hedger reads\n * (`useInstantOpens` / `useInstantCloses`) stay scoped to the sub-account.\n *\n * Every source is gated by `sources`, `enabled`, and a set `partyA`, then their\n * snapshots flow through the pure core `reconcileQuotes` (\"active quotes only\" —\n * a quote shows iff it is in a source this tick), stamping each optimistic\n * instant-open with its predicted VA via `instantOpenVaByTempId`. Live\n * notifications (via `useNotifications`, unless `live` is `false`) are applied in\n * the same merge. With `live` notifications the feature is **events-first**: it does\n * not poll at idle, only accelerating the on-chain reads briefly while a row awaits\n * on-chain confirmation (`shouldAccelerateOnchainReads`, the RPC-lag retry), and\n * falling back to a baseline poll only when the event channel is down.\n *\n * Optimistic instant-opens seeded into {@link useOptimisticQuotesStore} are\n * merged in as extra `instantOpens` so a just-submitted trade shows instantly,\n * then cleared once the same `tempQuoteId` lands on-chain.\n *\n * @example\n * ```tsx\n * const { quotes, accounts, socketStatus, isLoading } = useManagedQuotes({ partyA });\n * ```\n */\nexport function useManagedQuotes(parameters: UseManagedQuotesParameters): UseManagedQuotesResult {\n const { partyA, chainId, pollingInterval, live = true, enabled = true } = parameters;\n const config = useSymmioConfig();\n const defaultChainId = useSymmioChainId();\n const resolvedChainId = chainId ?? defaultChainId;\n const includeVirtualAccounts = parameters.includeVirtualAccounts ?? true;\n const extraAccounts = parameters.extraAccounts;\n const sources = parameters.sources;\n const wantOpenPositions = sources?.openPositions ?? true;\n const wantPendingQuotes = sources?.pendingQuotes ?? true;\n const wantInstantOpens = sources?.instantOpens ?? true;\n const wantInstantCloses = sources?.instantCloses ?? true;\n const active = enabled && Boolean(partyA);\n\n /**\n * Identity of the current account set's owner. VA retention (below) is scoped\n * to this `(chainId, partyA)` so switching sub-accounts never carries another\n * account's VAs into the read set.\n */\n const retentionOwner = active && partyA ? `${resolvedChainId}:${partyA.toLowerCase()}` : undefined;\n\n /**\n * VAs retained across the optimistic→on-chain hand-off. A predicted VA leaves\n * `predictedVas` the instant its instant-open lands on-chain (the hedger drops\n * the pending open), while `getVirtualAccountsAddressesOfSubAccount` and the\n * notification `va_address` can lag a poll behind — so without retention we'd\n * stop polling the exact VA the position just landed in, and the row would\n * vanish for a tick before reappearing as its `ONCHAIN` twin. VAs are\n * append-only on-chain, so once discovered we keep reading them while the owner\n * is unchanged. See reference-va-address-resolution in agent memory.\n */\n const [retained, setRetained] = useState<{ owner?: string; vas: Address[] }>({ vas: [] });\n const retainedVas = retained.owner === retentionOwner ? retained.vas : NO_RETAINED_VAS;\n\n /**\n * Notification-driven invalidation. Reads are kept in sync off the live\n * notifications stream — not polling — so the feature works with polling off.\n * `queryClient` and the cache scope (`configKey`) are mirrored into refs so the\n * `onNotification` callback below can stay referentially stable (a new callback\n * identity would resubscribe the socket). The debounce timer coalesces a burst\n * of notifications into one invalidation pass.\n */\n const queryClient = useQueryClient();\n const queryClientRef = useRef(queryClient);\n queryClientRef.current = queryClient;\n const configKey = config.getChainConfigKey(resolvedChainId);\n const configKeyRef = useRef(configKey);\n configKeyRef.current = configKey;\n const invalidateTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n /**\n * Which hedger feeds a debounced notification burst should invalidate. A burst\n * can mix open and close events, so the kinds are accumulated here across the\n * debounce window and read (then reset) when the timer fires — scoping the\n * invalidation to the feeds the events can actually affect.\n */\n const pendingInvalidationRef = useRef<{ opens: boolean; closes: boolean }>({ opens: false, closes: false });\n\n /**\n * Last reconciliation result, kept in a ref so it survives renders without\n * triggering one. Its only remaining job is to feed\n * {@link shouldAccelerateOnchainReads} (and the feed-intent gates) the previous\n * tick's result, since the source queries set their `refetchInterval` before this\n * render's result exists. (\"Active quotes only\" dropped the grace window, and\n * `links` are recomputed fresh on each merge.)\n */\n const previousRef = useRef<ReconcileQuotesResult | undefined>(undefined);\n\n /**\n * Rows anchored on a prior tick (a notification set their `quoteId`) but not yet\n * returned by the on-chain read — the previous merge's `pendingAnchors`. Fed back\n * into {@link reconcileQuotes} so an anchored row keeps showing while the RPC\n * catches up, instead of vanishing once the hedger drops its pending open. Held in\n * a ref so it survives renders without triggering one; the source query that\n * dropped the row drives the recompute that reads it.\n */\n const retainedAnchorsRef = useRef<UnifiedQuote[]>([]);\n\n /**\n * Last tick's socket status, read one render behind (like `previousRef`) to decide\n * whether the live event channel is up. Updated right after `useNotifications` below.\n * When the channel is live the feature is events-first (no idle poll); when it is\n * down we fall back to polling so state still advances without notifications.\n */\n const socketStatusRef = useRef<SocketStatus>(\"closed\");\n\n const optimisticEntries = useOptimisticQuotesStore((state) => state.entries);\n const clearSettled = useOptimisticQuotesStore((state) => state.clearSettled);\n\n /** Live event channel = subscribed (`live`) and the socket was `open` last render. */\n const eventChannelLive = live && socketStatusRef.current === \"open\";\n /** Consumer's opt-in idle cadence (off by default). */\n const idleInterval = pollingInterval && pollingInterval > 0 ? pollingInterval : false;\n\n /**\n * On-chain reads accelerate to {@link ACCELERATED_POLLING_INTERVAL} **only** while a\n * row awaits on-chain confirmation (`WRITE_ONCHAIN` / `WRITE_ONCHAIN_CLOSE` /\n * `CLOSING`) — the RPC-lag retry. Otherwise: no idle poll when the event channel is\n * live (events drive updates) unless the consumer opted into `idleInterval`; a\n * baseline fallback when the channel is down so state still progresses. Read from the\n * previous result because the queries set their interval before this render's result\n * exists (an on-chain poll / notification re-render advances it a tick later).\n */\n const accelerateOnchain = previousRef.current ? shouldAccelerateOnchainReads(previousRef.current) : false;\n const onchainIdleInterval = eventChannelLive ? idleInterval : idleInterval || FALLBACK_POLLING_INTERVAL;\n const refetchInterval = active ? (accelerateOnchain ? ACCELERATED_POLLING_INTERVAL : onchainIdleInterval) : false;\n\n /**\n * Hedger feeds are event-driven while the channel is live: the open/close mutation\n * invalidates the matching feed once and the notifications advance the stage, so they\n * do not poll (unless the consumer opted into `idleInterval`). When the channel is\n * down they poll while the matching flow is in flight, to track it without\n * notifications. `hasOpenIntent` / `hasCloseIntent` come from the previous tick.\n */\n const previousQuotes = previousRef.current?.quotes;\n const hasOpenIntent = previousQuotes?.some((quote) => OPEN_INTENT_LIFECYCLES.has(quote.lifecycle)) ?? false;\n const hasCloseIntent = previousQuotes?.some((quote) => CLOSE_INTENT_LIFECYCLES.has(quote.lifecycle)) ?? false;\n const feedInterval = (hasIntent: boolean) =>\n !eventChannelLive && hasIntent ? ACCELERATED_POLLING_INTERVAL : idleInterval;\n const instantOpensInterval = active && wantInstantOpens ? feedInterval(hasOpenIntent) : false;\n const instantClosesInterval = active && wantInstantCloses ? feedInterval(hasCloseIntent) : false;\n\n /**\n * Off-chain hedger reads — always scoped to the sub-account, never the VAs. Kept\n * `enabled` so a mutation's `onSuccess` invalidation can fetch them on demand, but\n * polled only while the matching flow is in flight (see the interval gates above).\n */\n const instantOpens = useInstantOpens({\n partyA: partyA as Address,\n chainId: resolvedChainId,\n query: { enabled: active && wantInstantOpens, refetchInterval: instantOpensInterval },\n });\n\n const instantCloses = useInstantCloses({\n partyA: partyA as Address,\n chainId: resolvedChainId,\n query: { enabled: active && wantInstantCloses, refetchInterval: instantClosesInterval },\n });\n\n /** The sub-account's existing on-chain VAs. Empty (harmless) when `partyA` is itself a VA. */\n const virtualAccounts = useVirtualAccountsAddressesOfSubAccount({\n subAccount: partyA,\n chainId: resolvedChainId,\n query: { enabled: active && includeVirtualAccounts, refetchInterval },\n });\n\n /**\n * Brand-new-VA bridge: a position can open in a market the sub-account has\n * never traded, landing in a freshly created VA that is not yet in\n * `getVirtualAccountsAddressesOfSubAccount`. The predicted VA below covers it\n * while the instant-open is pending; once it lands on-chain the hedger drops the\n * open and the prediction with it, so VA retention (`retained`, above) keeps the\n * VA in the poll set across the hand-off — the row transitions to `ONCHAIN` in\n * place instead of flickering out and back.\n */\n\n /**\n * Predict the VA each pending instant-open will land in. The set of opens is\n * dynamic, but `useQueries` over a dynamic array is allowed — the hook count\n * stays one regardless of length.\n */\n const pendingOpens = wantInstantOpens ? (instantOpens.data ?? []) : [];\n const predictedVas = useQueries({\n queries: pendingOpens.map((open) => ({\n ...getPredictedNextVirtualAccountQueryOptions(config, {\n subAccount: partyA,\n chainId: resolvedChainId,\n isolationType: isolationTypeForSide(open.positionType),\n symbolId: BigInt(open.marketId),\n query: { enabled: active && includeVirtualAccounts, refetchInterval },\n }),\n })),\n combine: (results) => ({\n byTempId: pendingOpens.reduce<Record<number, Address>>((map, open, index) => {\n const predicted = results[index]?.data;\n if (predicted) map[open.tempQuoteId] = getAddress(predicted);\n return map;\n }, {}),\n addresses: results.map((result) => result.data).filter((address): address is Address => Boolean(address)),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n }),\n });\n\n const [notifications, setNotifications] = useState<Notification[]>([]);\n const { status: socketStatus } = useNotifications({\n account: partyA,\n chainId: resolvedChainId,\n enabled: active && live,\n onNotification: useCallback((notification: Notification) => {\n setNotifications((prev) => [...prev, notification].slice(-NOTIFICATION_BUFFER_LIMIT));\n // Solver notification carries both `tempQuoteId` and the on-chain\n // `quoteId` on the frame that anchors a pre-chain quote. Link the two\n // in the TP/SL store so a record that was written under the temp id\n // (via `useSetQuoteTpSl` post-instant-open) is instantly reachable via\n // the on-chain id once the anchor lands — no re-fetch needed.\n const tempId = notification.tempQuoteId;\n const onchainStr = notification.quoteId;\n if (tempId && onchainStr && onchainStr !== `${tempId}`) {\n useTpSlStore.getState().link(BigInt(tempId), BigInt(onchainStr));\n }\n /**\n * Refetch the authoritative reads off the live event so both tables stay in\n * sync without polling. The on-chain reads always refresh (any lifecycle event\n * can change them); the hedger feeds refresh only for the matching flow, so an\n * open event never re-fetches the closes feed and vice versa. Kinds are\n * accumulated across the debounce window because a burst can mix open and close\n * events. Scoped to this chain (`configKey`); React Query dedups concurrent\n * refetches of the same query.\n */\n const kind = classifyQuoteNotificationAction(notification.lastSeenAction);\n const pending = pendingInvalidationRef.current;\n if (kind === \"open\") pending.opens = true;\n else if (kind === \"close\") pending.closes = true;\n else {\n pending.opens = true;\n pending.closes = true;\n }\n if (invalidateTimerRef.current) clearTimeout(invalidateTimerRef.current);\n invalidateTimerRef.current = setTimeout(() => {\n const client = queryClientRef.current;\n const scope = { configKey: configKeyRef.current };\n const { opens, closes } = pendingInvalidationRef.current;\n pendingInvalidationRef.current = { opens: false, closes: false };\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAOpenPositionsQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAPendingQuotesQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getQuoteQueryKey, scope) });\n if (opens) void client.invalidateQueries({ predicate: predicateMatch(getInstantOpensQueryKey, scope) });\n if (closes) void client.invalidateQueries({ predicate: predicateMatch(getInstantClosesQueryKey, scope) });\n }, NOTIFICATION_INVALIDATE_DEBOUNCE);\n }, []),\n });\n\n /** Mirror the live socket status into the ref the interval gating reads next render. */\n socketStatusRef.current = socketStatus;\n\n /**\n * One-shot re-sync when the notifications socket **reconnects**. The stream does not\n * replay messages missed while it was down, so on a re-`open` we invalidate the reads\n * once to catch up — this replaces a continuous fallback poll. The first connect is\n * skipped (the queries already fetched on mount).\n */\n const hasBeenOpenRef = useRef(false);\n useEffect(() => {\n if (!live || socketStatus !== \"open\") return;\n if (hasBeenOpenRef.current) {\n const client = queryClientRef.current;\n const scope = { configKey: configKeyRef.current };\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAOpenPositionsQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getPartyAPendingQuotesQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getQuoteQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getInstantOpensQueryKey, scope) });\n void client.invalidateQueries({ predicate: predicateMatch(getInstantClosesQueryKey, scope) });\n }\n hasBeenOpenRef.current = true;\n }, [socketStatus, live]);\n\n /** Clear the pending invalidation timer on unmount. */\n useEffect(() => {\n return () => {\n if (invalidateTimerRef.current) clearTimeout(invalidateTimerRef.current);\n };\n }, []);\n\n /** Distinct VA addresses seen on the notifications stream. */\n const notificationVas = useMemo<Address[]>(() => {\n const seen = new Set<string>();\n const result: Address[] = [];\n for (const notification of notifications) {\n if (!notification.vaAddress) continue;\n const checksummed = getAddress(notification.vaAddress);\n const lower = checksummed.toLowerCase();\n if (seen.has(lower)) continue;\n seen.add(lower);\n result.push(checksummed);\n }\n return result;\n }, [notifications]);\n\n /**\n * The deduplicated (case-insensitive), checksummed set of on-chain accounts to\n * read quotes across — the sub-account, its VAs, the predicted VAs, the\n * notification VAs, and any extras. Order: sub-account first, then the rest.\n */\n const accounts = useMemo<Address[]>(() => {\n if (!active || !partyA) return [];\n const seen = new Set<string>();\n const result: Address[] = [];\n const add = (address: Address) => {\n const checksummed = getAddress(address);\n const lower = checksummed.toLowerCase();\n if (seen.has(lower)) return;\n seen.add(lower);\n result.push(checksummed);\n };\n add(partyA);\n if (includeVirtualAccounts) {\n for (const virtualAccount of virtualAccounts.data ?? []) add(virtualAccount);\n for (const predicted of predictedVas.addresses) add(predicted);\n for (const notificationVa of notificationVas) add(notificationVa);\n for (const retainedVa of retainedVas) add(retainedVa);\n }\n for (const extra of extraAccounts ?? []) add(extra);\n return result;\n }, [\n active,\n partyA,\n includeVirtualAccounts,\n virtualAccounts.data,\n predictedVas.addresses,\n notificationVas,\n retainedVas,\n extraAccounts,\n ]);\n\n /**\n * Accumulate every VA we discover (list + predicted + notification) into the\n * retained set so none ever leaves the poll set mid-hand-off. Monotonic per\n * owner; resets when the owner `(chainId, partyA)` changes. Setting state only\n * when something new appears keeps this from looping.\n */\n useEffect(() => {\n if (!retentionOwner) return;\n const discovered = [...(virtualAccounts.data ?? []), ...predictedVas.addresses, ...notificationVas];\n setRetained((prev) => {\n const carryOver = prev.owner === retentionOwner ? prev.vas : [];\n const seen = new Set(carryOver.map((address) => address.toLowerCase()));\n const next = [...carryOver];\n let changed = prev.owner !== retentionOwner;\n for (const va of discovered) {\n const checksummed = getAddress(va);\n const lower = checksummed.toLowerCase();\n if (seen.has(lower)) continue;\n seen.add(lower);\n next.push(checksummed);\n changed = true;\n }\n return changed ? { owner: retentionOwner, vas: next } : prev;\n });\n }, [retentionOwner, virtualAccounts.data, predictedVas.addresses, notificationVas]);\n\n /** On-chain open positions, fanned out across every account, flattened to one `Quote[]`. */\n const openPositions = useQueries({\n queries: accounts.map((account) => {\n const options = getPartyAOpenPositionsQueryOptions(config, {\n partyA: account,\n chainId: resolvedChainId,\n query: { enabled: active && wantOpenPositions, refetchInterval },\n });\n return {\n ...options,\n queryFn: async () => {\n try {\n return await options.queryFn();\n } catch (err) {\n throw normalizeSymmError(err);\n }\n },\n };\n }),\n combine: (results) => ({\n quotes: results.flatMap((result) => result.data ?? []),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n error: (results.find((result) => result.error)?.error as SymmioRequestError | undefined) ?? null,\n refetch: () => results.forEach((result) => result.refetch()),\n }),\n });\n /** Pending quote ids, fanned out across every account, then hydrated per id. */\n const pendingQuoteIds = useQueries({\n queries: accounts.map((account) => {\n const options = getPartyAPendingQuotesQueryOptions(config, {\n partyA: account,\n chainId: resolvedChainId,\n query: { enabled: active && wantPendingQuotes, refetchInterval },\n });\n return {\n ...options,\n queryFn: async () => {\n try {\n return await options.queryFn();\n } catch (err) {\n throw normalizeSymmError(err);\n }\n },\n };\n }),\n combine: (results) => ({\n ids: results.flatMap((result) => result.data ?? []),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n error: (results.find((result) => result.error)?.error as SymmioRequestError | undefined) ?? null,\n refetch: () => results.forEach((result) => result.refetch()),\n }),\n });\n\n const hydratedPending = useQueries({\n queries: pendingQuoteIds.ids.map((quoteId) => {\n const options = getQuoteQueryOptions(config, {\n quoteId,\n chainId: resolvedChainId,\n query: { enabled: active && wantPendingQuotes, refetchInterval },\n });\n return {\n ...options,\n queryFn: async () => {\n try {\n return await options.queryFn();\n } catch (err) {\n throw normalizeSymmError(err);\n }\n },\n };\n }),\n combine: (results) => ({\n quotes: results.map((result) => result.data).filter((quote): quote is Quote => Boolean(quote)),\n isLoading: results.some((result) => result.isLoading),\n isFetching: results.some((result) => result.isFetching),\n error: (results.find((result) => result.error)?.error as SymmioRequestError | undefined) ?? null,\n }),\n });\n\n const result = useMemo<ReconcileQuotesResult>(() => {\n if (!active || !partyA) {\n previousRef.current = undefined;\n retainedAnchorsRef.current = [];\n return { quotes: [], links: {}, pendingAnchors: [] };\n }\n const seededInstantOpens = [...(instantOpens.data ?? []), ...Object.values(optimisticEntries)];\n const next = reconcileQuotes({\n partyA,\n onchainPositions: wantOpenPositions ? openPositions.quotes : [],\n onchainPendingQuotes: wantPendingQuotes ? hydratedPending.quotes : [],\n instantOpens: wantInstantOpens ? seededInstantOpens : [],\n instantCloses: wantInstantCloses ? (instantCloses.data ?? []) : [],\n instantOpenVaByTempId: predictedVas.byTempId,\n notifications,\n retainedAnchors: retainedAnchorsRef.current,\n });\n previousRef.current = next;\n retainedAnchorsRef.current = next.pendingAnchors;\n return next;\n }, [\n active,\n partyA,\n openPositions.quotes,\n hydratedPending.quotes,\n instantOpens.data,\n instantCloses.data,\n predictedVas.byTempId,\n optimisticEntries,\n notifications,\n wantOpenPositions,\n wantPendingQuotes,\n wantInstantOpens,\n wantInstantCloses,\n ]);\n\n const byKey = useMemo<Record<string, UnifiedQuote>>(() => {\n const map: Record<string, UnifiedQuote> = {};\n for (const quote of result.quotes) map[quote.key] = quote;\n return map;\n }, [result.quotes]);\n\n /**\n * Drop optimistic seeds once their `tempQuoteId` has been **confirmed by the\n * on-chain read** — the linked row carries the polled struct (`raw.onchain`).\n * Clearing on the notification link alone would drop the seed while the row is\n * still `WRITE_ONCHAIN`, before any source but the notification holds it, so the\n * row would flicker out until the RPC catches up.\n */\n useEffect(() => {\n const settled = Object.keys(optimisticEntries)\n .map(Number)\n .filter((tempQuoteId) => {\n const key = result.links[tempQuoteId];\n return key !== undefined && byKey[key]?.raw.onchain !== undefined;\n });\n if (settled.length > 0) clearSettled(settled);\n }, [result, byKey, optimisticEntries, clearSettled]);\n\n const isLoading =\n (active && includeVirtualAccounts && virtualAccounts.isLoading) ||\n (active && includeVirtualAccounts && predictedVas.isLoading) ||\n (active && wantOpenPositions && openPositions.isLoading) ||\n (active && wantPendingQuotes && (pendingQuoteIds.isLoading || hydratedPending.isLoading)) ||\n (active && wantInstantOpens && instantOpens.isLoading) ||\n (active && wantInstantCloses && instantCloses.isLoading);\n\n const isFetching =\n (includeVirtualAccounts && (virtualAccounts.isFetching || predictedVas.isFetching)) ||\n (wantOpenPositions && openPositions.isFetching) ||\n (wantPendingQuotes && (pendingQuoteIds.isFetching || hydratedPending.isFetching)) ||\n (wantInstantOpens && instantOpens.isFetching) ||\n (wantInstantCloses && instantCloses.isFetching);\n\n const error =\n openPositions.error ??\n pendingQuoteIds.error ??\n hydratedPending.error ??\n virtualAccounts.error ??\n instantOpens.error ??\n instantCloses.error ??\n null;\n\n /**\n * `openPositions` / `pendingQuoteIds` are `useQueries` fan-outs (no single\n * query handle), so their combined results expose a `refetch` that fires every\n * per-account query. Refetching the ids re-drives the per-id hydration.\n */\n const refetchOpenPositions = openPositions.refetch;\n const refetchPendingQuoteIds = pendingQuoteIds.refetch;\n const refetch = useCallback(() => {\n if (includeVirtualAccounts) virtualAccounts.refetch();\n if (wantOpenPositions) refetchOpenPositions();\n if (wantPendingQuotes) refetchPendingQuoteIds();\n if (wantInstantOpens) instantOpens.refetch();\n if (wantInstantCloses) instantCloses.refetch();\n }, [\n includeVirtualAccounts,\n wantOpenPositions,\n wantPendingQuotes,\n wantInstantOpens,\n wantInstantCloses,\n virtualAccounts,\n refetchOpenPositions,\n refetchPendingQuoteIds,\n instantOpens,\n instantCloses,\n ]);\n\n return {\n quotes: result.quotes,\n byKey,\n accounts,\n isLoading: Boolean(isLoading),\n isFetching: Boolean(isFetching),\n socketStatus: live ? socketStatus : \"closed\",\n error,\n refetch,\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { ConfigParameter, GetPartyAOpenPositionsOptions, GetPartyAOpenPositionsReturnType } from '@symmio/trading-core';
2
2
  import { UseQueryResult } from '@tanstack/react-query';
3
- import { SymmioRequestError } from '../errors/symmio-request-error';
3
+ import { SymmioRequestError } from '../errors/symmio-request-error.js';
4
4
  /**
5
5
  * Parameters for {@link usePartyAOpenPositions}: the core query options (partyA,
6
6
  * pagination, chain id, TanStack `query` overrides) plus an optional `config`.
@@ -10,9 +10,9 @@ export type UsePartyAOpenPositionsParameters = GetPartyAOpenPositionsOptions & C
10
10
  export type UsePartyAOpenPositionsReturnType = UseQueryResult<GetPartyAOpenPositionsReturnType, SymmioRequestError>;
11
11
  /**
12
12
  * Read a partyA's open positions (full `Quote` structs) from the SYMMIO core.
13
- * `partyA` is a SubAccount (Majors) or Virtual Account (VibeCaps). The query is
14
- * disabled until `partyA` is set. `chainId` defaults to the connected chain.
15
- * Errors are normalized to {@link SymmioRequestError}.
13
+ * `partyA` is a virtual account (lowcap). The query is disabled until `partyA`
14
+ * is set. `chainId` defaults to the connected chain. Errors are normalized to
15
+ * {@link SymmioRequestError}.
16
16
  *
17
17
  * @example
18
18
  * ```tsx