@totalis/hip4-client 0.80.0 → 0.82.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,51 @@
3
3
  `@totalis/hip4-client` follows [semantic versioning](https://semver.org).
4
4
  The contract version the generated types come from is `sdkVersion` in `./version`.
5
5
 
6
+ ## 0.82.0
7
+
8
+ ### Changed
9
+
10
+ - `GAS_PRICE_ABOVE_CEILING` (503, `BACKOFF`) moves from opening RFQs to
11
+ accepting them (TT-2637): `createRfq`, `createCashout` and `createGoldenRfq`
12
+ no longer answer it, so quotes keep coming during a HyperEVM gas spike, and
13
+ `acceptQuote` (entry and cash-out) answers it, like `placeGolden`, while the
14
+ gas price is above 30 gwei. Nothing is placed or accepted; an exact replay
15
+ of an accepted quote still answers.
16
+
17
+ ### Added
18
+
19
+ - The market stream's `network` subscription flag and `network` frame: the
20
+ HyperEVM gas price, the level Totalis accepts quotes at
21
+ (`accept_below_wei`) and the current spike's `peak_wei`, after every
22
+ snapshot and on every change the app acts on, so a client can tell before
23
+ a press that an accept would be refused. Contract `209.0.0-gas-at-accept`.
24
+
25
+ ## 0.81.1
26
+
27
+ ### Changed
28
+
29
+ - Generated types: the `actions` description on maker capital reads now says
30
+ `MAKER_QUOTE` carries an amount, `free_after_pending` less a live v1
31
+ withdrawal request's amount, instead of always being null (TT-2567). No type
32
+ changed.
33
+
34
+ ## 0.81.0
35
+
36
+ ### Added
37
+
38
+ - `totalis.readComboCash()`: what one Combo can stake now, from one
39
+ `GET /v1/me/balances` read and the signer's HyperCore cash read from
40
+ Hyperliquid (TT-2572). It answers `vault`, `wallet`, `core` (spot USDC less
41
+ its hold), `coreMode`, `setupFee`, `offeredCore` and `allowance`, each `null`
42
+ when unknown. Pass it as `cash` and `offeredCore` as `core` to `openPosition`,
43
+ `signEntry` or `prepareEntryFunding`; `allowance` is the largest stake they
44
+ plan from it. A Portfolio Margin account offers no Core, as in the Totalis app.
45
+ - `offeredCore(spendable, setupFee)` and `comboAllowance({ vault, wallet, core })`,
46
+ the same rule as plain functions.
47
+ - `readCoreCash(network, account, info?)`, `hyperliquidInfo(fetch?)`,
48
+ `coreSetupFee` and `infoUrl` on `hyperliquidNetwork`, for reading HyperCore
49
+ cash yourself.
50
+
6
51
  ## 0.80.0
7
52
 
8
53
  ### Added
package/dist/client.d.ts CHANGED
@@ -5,12 +5,12 @@ export type { components, operations, paths } from "./generated/client.js";
5
5
  export type { AccessToken, ApiClientOptions, PublicEnvironment } from "./base.js";
6
6
  /** The typed HTTP client for the `client` audience. `createTotalis` adds the flows. */
7
7
  export declare function createClient(environment: PublicEnvironment, options?: ApiClientOptions): import("openapi-fetch").Client<paths, `${string}/${string}`>;
8
- export { bestBid, bestQuote, createTotalis, EntryError, entryFailure, follow, type Acceptance, type AcceptanceResult, type Amount, type BridgeState, type CashoutBid, type Chooser, type Deployment, type DepositAccepted, type EntryCash, type EntryFailure, type EntryQuote, type CoreExit, type LegacySignedEntry, type Leg, type PreparedEntryFunding, type NotAdmitted, type RecordListener, type Operation, type Quote, type ResponseOf, type SellBackQuote, type SignedAcceptance, type SignedCashout, type SignedCoreExit, type SignedDeposit, type SignedEntry, type SignedReturnToCore, type Totalis, type TotalisOptions, type TransferQuote, type WalletCall, type Withdrawal, } from "./totalis.js";
9
- export { bridgeAction, bridgeGasBuffer, classifyHypercoreAnswer, hyperevmUsdcBridge, hyperliquidExchange, hyperliquidNetwork, hypercoreNonce, hypercoreSignature, sendAssetTypedData, settleHypercore, signSendAsset, submitHypercore, usdcText, type BridgedCash, type HypercoreAnswer, type HypercoreSignature, type HypercoreTransport, type HyperliquidNetwork, type SendAssetAction, type SignedSendAsset, } from "./hypercore.js";
8
+ export { bestBid, bestQuote, createTotalis, EntryError, entryFailure, follow, type Acceptance, type AcceptanceResult, type Amount, type BridgeState, type ComboCash, type CashoutBid, type Chooser, type Deployment, type DepositAccepted, type EntryCash, type EntryFailure, type EntryQuote, type CoreExit, type LegacySignedEntry, type Leg, type PreparedEntryFunding, type NotAdmitted, type RecordListener, type Operation, type Quote, type ResponseOf, type SellBackQuote, type SignedAcceptance, type SignedCashout, type SignedCoreExit, type SignedDeposit, type SignedEntry, type SignedReturnToCore, type Totalis, type TotalisOptions, type TransferQuote, type WalletCall, type Withdrawal, } from "./totalis.js";
9
+ export { bridgeAction, bridgeGasBuffer, classifyHypercoreAnswer, coreSetupFee, hyperevmUsdcBridge, hyperliquidExchange, hyperliquidInfo, hyperliquidNetwork, hypercoreNonce, hypercoreSignature, readCoreCash, sendAssetTypedData, settleHypercore, signSendAsset, submitHypercore, usdcText, type BridgedCash, type CoreAccountMode, type CoreCash, type HypercoreAnswer, type HyperliquidInfo, type HypercoreSignature, type HypercoreTransport, type HyperliquidNetwork, type SendAssetAction, type SignedSendAsset, } from "./hypercore.js";
10
10
  export { ApiError, envelope, NetworkError, randomBytes32, retryingFetch, sendOnce, unwrap, uuidv7, type Fetch, type Repaired, type RetryPolicy } from "./request.js";
11
11
  export { items, pages, type Page, type PageQuery } from "./pagination.js";
12
12
  export { toTotalisSigner, type SignerInput, type TotalisSigner } from "./signer.js";
13
13
  export { BalanceUnknownError, ExitUnavailableError, normalizeError, type NormalizedError } from "./flow-errors.js";
14
- export { netCashout, netOfProfitFee, netPayout, netStake, spendableCash } from "./money.js";
14
+ export { comboAllowance, netCashout, netOfProfitFee, netPayout, netStake, offeredCore, spendableCash } from "./money.js";
15
15
  export { createUiAdapter, type AccountResource, type QuoteView, type UiAdapter, type UiAdapterOptions } from "./ui.js";
16
16
  export { StreamClosedError, TotalisStream, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscription } from "./stream.js";
package/dist/client.js CHANGED
@@ -5,11 +5,11 @@ export function createClient(environment, options) {
5
5
  return audienceClient(environment, options);
6
6
  }
7
7
  export { bestBid, bestQuote, createTotalis, EntryError, entryFailure, follow, } from "./totalis.js";
8
- export { bridgeAction, bridgeGasBuffer, classifyHypercoreAnswer, hyperevmUsdcBridge, hyperliquidExchange, hyperliquidNetwork, hypercoreNonce, hypercoreSignature, sendAssetTypedData, settleHypercore, signSendAsset, submitHypercore, usdcText, } from "./hypercore.js";
8
+ export { bridgeAction, bridgeGasBuffer, classifyHypercoreAnswer, coreSetupFee, hyperevmUsdcBridge, hyperliquidExchange, hyperliquidInfo, hyperliquidNetwork, hypercoreNonce, hypercoreSignature, readCoreCash, sendAssetTypedData, settleHypercore, signSendAsset, submitHypercore, usdcText, } from "./hypercore.js";
9
9
  export { ApiError, envelope, NetworkError, randomBytes32, retryingFetch, sendOnce, unwrap, uuidv7 } from "./request.js";
10
10
  export { items, pages } from "./pagination.js";
11
11
  export { toTotalisSigner } from "./signer.js";
12
12
  export { BalanceUnknownError, ExitUnavailableError, normalizeError } from "./flow-errors.js";
13
- export { netCashout, netOfProfitFee, netPayout, netStake, spendableCash } from "./money.js";
13
+ export { comboAllowance, netCashout, netOfProfitFee, netPayout, netStake, offeredCore, spendableCash } from "./money.js";
14
14
  export { createUiAdapter } from "./ui.js";
15
15
  export { StreamClosedError, TotalisStream } from "./stream.js";
@@ -481,7 +481,7 @@ export type components = {
481
481
  readonly floor_bps: number | null;
482
482
  /** @description SHA-256 of the exact pinned artifact that names this deployment's chain and vault: the release artifact on chain 999, the environment's deployment manifest on 998. A client compares it with its own pinned artifact to bind the read to its deployment. */
483
483
  readonly deployment_digest: string;
484
- /** @description Decisions for MAKER_WITHDRAW and MAKER_QUOTE on the MAKER_VAULT route. MAKER_WITHDRAW is the amount a new withdrawal request may ask for: free_after_pending, so it never takes collateral from fills already admitted. The vault re-checks free collateral when the request executes after its delay; it is null with MAKER_WITHDRAW_PENDING while a request is live, or with a reconciliation blocker. MAKER_QUOTE is always null with one blocker, because quoting capacity depends on state only the maker's bot holds, such as its other live quotes. PRIVATE_QUOTE_CAPACITY_UNAVAILABLE means only that Totalis cannot compute that amount; it does not mean quoting is off, and the maker can keep quoting. A reconciliation blocker replaces it while the vault read and venue records disagree. */
484
+ /** @description Decisions for MAKER_WITHDRAW and MAKER_QUOTE on the MAKER_VAULT route. MAKER_WITHDRAW is the amount a new withdrawal request may ask for: free_after_pending, so it never takes collateral from fills already admitted. The vault re-checks free collateral when the request executes after its delay; it is null with MAKER_WITHDRAW_PENDING while a request is live, or with a reconciliation blocker. MAKER_QUOTE is the most new quotes may promise: free_after_pending less a live v1 withdrawal request's amount, never below zero. Quotes reserve nothing, so it does not count the maker's other live quotes; if several are accepted at once, a confirm past it fails QUOTE_CAPACITY_EXCEEDED. Both are null with a reconciliation blocker while the vault read and venue records disagree. */
485
485
  readonly actions: readonly components["schemas"]["ActionAvailability"][];
486
486
  /** @description Venue reservations on MAKER_VAULT that make up pending_commitments. */
487
487
  readonly reservations: readonly components["schemas"]["Reservation"][];
@@ -369,7 +369,7 @@ export type CloseReason = "SUBPROTOCOL_REQUIRED" | "CURSOR_RESET" | "DEPENDENCY_
369
369
  /** The codes each live operation can return. */
370
370
  export declare const operationErrors: {
371
371
  readonly abandonCoreExit: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "NOT_FOUND", "STATE_CONFLICT", "ORIGIN_REQUIRED"];
372
- readonly acceptQuote: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_NOT_OPEN", "QUOTE_EXPIRED", "QUOTE_CANCELLED", "QUOTE_REPLACED", "QUOTE_SIGNER_CHANGED", "QUOTE_CAPACITY_EXCEEDED", "QUOTE_NOT_FOUND", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "INVALID_SIGNATURE", "CONTRACT_SIGNATURE_OVERLOADED", "EXECUTION_BACKLOG_FULL", "CORE_MOVE_IN_FLIGHT", "ACCEPTANCE_IN_FLIGHT", "GOLDEN_CASHOUT_REFUSED", "NOT_FOUND", "ORIGIN_REQUIRED", "WRONG_AUTHORITY"];
372
+ readonly acceptQuote: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_NOT_OPEN", "QUOTE_EXPIRED", "QUOTE_CANCELLED", "QUOTE_REPLACED", "QUOTE_SIGNER_CHANGED", "QUOTE_CAPACITY_EXCEEDED", "QUOTE_NOT_FOUND", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "INVALID_SIGNATURE", "CONTRACT_SIGNATURE_OVERLOADED", "EXECUTION_BACKLOG_FULL", "CORE_MOVE_IN_FLIGHT", "ACCEPTANCE_IN_FLIGHT", "GOLDEN_CASHOUT_REFUSED", "GAS_PRICE_ABOVE_CEILING", "NOT_FOUND", "ORIGIN_REQUIRED", "WRONG_AUTHORITY"];
373
373
  readonly activeCoreExits: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED"];
374
374
  readonly admitOwnMaker: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "ORIGIN_REQUIRED", "INVALID_REQUEST", "NOT_FOUND", "STATE_CONFLICT"];
375
375
  readonly admitPartnerWallet: readonly ["INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "UNAUTHENTICATED", "FORBIDDEN", "STATE_CONFLICT", "INVALID_SIGNATURE", "RATE_LIMITED", "AUTHORIZATION_UNAVAILABLE"];
@@ -379,19 +379,19 @@ export declare const operationErrors: {
379
379
  readonly confirmComboCopyAgent: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "RATE_LIMITED", "ORIGIN_REQUIRED", "IDENTITY_NOT_FOUND", "CONTRACT_UNAVAILABLE", "NOT_FOUND", "STATE_CONFLICT", "DEPENDENCY_STALE", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED"];
380
380
  readonly confirmCoreCopyAgent: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "RATE_LIMITED", "ORIGIN_REQUIRED", "IDENTITY_NOT_FOUND", "CONTRACT_UNAVAILABLE", "NOT_FOUND", "STATE_CONFLICT", "DEPENDENCY_STALE", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED"];
381
381
  readonly confirmQuote: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "NOT_FOUND", "STATE_CONFLICT", "INVALID_SIGNATURE", "QUOTE_EXPIRED", "QUOTE_SIGNER_CHANGED", "QUOTE_CAPACITY_EXCEEDED", "QUOTE_EXPOSURE_LIMIT", "QUOTE_EXPOSURE_STALE", "COMBO_AUTOMATIC_DISABLED", "RFQ_GENERATION_STALE", "FINANCIAL_ACTIONS_DISABLED", "WRONG_AUTHORITY"];
382
- readonly createCashout: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_INTENT_LIMIT", "STATE_CONFLICT", "GOLDEN_CASHOUT_REFUSED", "FINANCIAL_ACTIONS_DISABLED", "GAS_PRICE_ABOVE_CEILING", "ORIGIN_REQUIRED"];
382
+ readonly createCashout: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_INTENT_LIMIT", "STATE_CONFLICT", "GOLDEN_CASHOUT_REFUSED", "FINANCIAL_ACTIONS_DISABLED", "ORIGIN_REQUIRED"];
383
383
  readonly createCollateralReduction: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "NOT_FOUND", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "COLLATERAL_REDUCTION_UNAVAILABLE"];
384
384
  readonly createComment: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "ORIGIN_REQUIRED", "IDENTITY_NOT_FOUND", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "STATE_CONFLICT"];
385
385
  readonly createCoreExit: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "CORE_EXIT_UNAVAILABLE", "CORE_ACCOUNT_NOT_READY", "CORE_ACCOUNT_ACTIVATION_REQUIRED", "CORE_MOVE_IN_FLIGHT", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "ORIGIN_REQUIRED"];
386
386
  readonly createDeposit: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "INVALID_SIGNATURE", "SPONSORSHIP_UNAVAILABLE", "ORIGIN_REQUIRED"];
387
- readonly createGoldenRfq: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "ORIGIN_REQUIRED", "IDENTITY_NOT_FOUND", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "CONTRACT_UNAVAILABLE", "GOLDEN_TICKET_NONE", "GOLDEN_TICKET_USED", "GOLDEN_TICKET_EXPIRED", "GOLDEN_PLACEMENT_IN_FLIGHT", "GOLDEN_LEG_COUNT", "GOLDEN_LEG_NOT_ELIGIBLE", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "GAS_PRICE_ABOVE_CEILING", "COMBO_AUTOMATIC_DISABLED", "BROWSE_UNAVAILABLE"];
387
+ readonly createGoldenRfq: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "ORIGIN_REQUIRED", "IDENTITY_NOT_FOUND", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "CONTRACT_UNAVAILABLE", "GOLDEN_TICKET_NONE", "GOLDEN_TICKET_USED", "GOLDEN_TICKET_EXPIRED", "GOLDEN_PLACEMENT_IN_FLIGHT", "GOLDEN_LEG_COUNT", "GOLDEN_LEG_NOT_ELIGIBLE", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "COMBO_AUTOMATIC_DISABLED", "BROWSE_UNAVAILABLE"];
388
388
  readonly createMakerApiKey: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "IDEMPOTENCY_KEY_REUSED", "SECRET_UNAVAILABLE", "KEY_LIMIT_REACHED"];
389
389
  readonly createMakerApiKeyChallenge: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "IDEMPOTENCY_KEY_REUSED"];
390
390
  readonly createOperatorApiKey: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "IDEMPOTENCY_KEY_REUSED", "SECRET_UNAVAILABLE", "KEY_LIMIT_REACHED"];
391
391
  readonly createPersonalApiKey: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "IDEMPOTENCY_KEY_REUSED", "SECRET_UNAVAILABLE", "KEY_LIMIT_REACHED"];
392
392
  readonly createPersonalApiKeyChallenge: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "IDEMPOTENCY_KEY_REUSED"];
393
393
  readonly createQuote: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_NOT_OPEN", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "NOT_FOUND"];
394
- readonly createRfq: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_INTENT_LIMIT", "RFQ_GENERATION_STALE", "RFQ_GENERATION_IN_FLIGHT", "STATE_CONFLICT", "COMBO_AUTOMATIC_DISABLED", "FINANCIAL_ACTIONS_DISABLED", "GAS_PRICE_ABOVE_CEILING", "ORIGIN_REQUIRED"];
394
+ readonly createRfq: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "NOT_FOUND", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "RFQ_INTENT_LIMIT", "RFQ_GENERATION_STALE", "RFQ_GENERATION_IN_FLIGHT", "STATE_CONFLICT", "COMBO_AUTOMATIC_DISABLED", "FINANCIAL_ACTIONS_DISABLED", "ORIGIN_REQUIRED"];
395
395
  readonly createRunOffClaim: readonly ["UNAUTHENTICATED", "FORBIDDEN", "AUTHORIZATION_UNAVAILABLE", "DEPENDENCY_STALE", "RATE_LIMITED", "INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSED", "STATE_CONFLICT", "FINANCIAL_ACTIONS_DISABLED", "ORIGIN_REQUIRED"];
396
396
  readonly createWalletChallenge: readonly ["INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "ORIGIN_REQUIRED", "ORIGIN_NOT_ALLOWED", "UNAUTHENTICATED", "IDEMPOTENCY_KEY_REUSED", "STATE_CONFLICT", "WALLET_CONTRACT_UNSUPPORTED", "RATE_LIMITED", "AUTHORIZATION_UNAVAILABLE"];
397
397
  readonly createWalletSession: readonly ["INVALID_REQUEST", "INVALID_IDEMPOTENCY_KEY", "ORIGIN_REQUIRED", "ORIGIN_NOT_ALLOWED", "UNAUTHENTICATED", "ACCESS_REQUIRED", "IDEMPOTENCY_KEY_REUSED", "STATE_CONFLICT", "INVALID_SIGNATURE", "RATE_LIMITED", "AUTHORIZATION_UNAVAILABLE"];
@@ -402,6 +402,7 @@ export const operationErrors = {
402
402
  "CORE_MOVE_IN_FLIGHT",
403
403
  "ACCEPTANCE_IN_FLIGHT",
404
404
  "GOLDEN_CASHOUT_REFUSED",
405
+ "GAS_PRICE_ABOVE_CEILING",
405
406
  "NOT_FOUND",
406
407
  "ORIGIN_REQUIRED",
407
408
  "WRONG_AUTHORITY"
@@ -537,7 +538,6 @@ export const operationErrors = {
537
538
  "STATE_CONFLICT",
538
539
  "GOLDEN_CASHOUT_REFUSED",
539
540
  "FINANCIAL_ACTIONS_DISABLED",
540
- "GAS_PRICE_ABOVE_CEILING",
541
541
  "ORIGIN_REQUIRED"
542
542
  ],
543
543
  "createCollateralReduction": [
@@ -619,7 +619,6 @@ export const operationErrors = {
619
619
  "GOLDEN_LEG_NOT_ELIGIBLE",
620
620
  "STATE_CONFLICT",
621
621
  "FINANCIAL_ACTIONS_DISABLED",
622
- "GAS_PRICE_ABOVE_CEILING",
623
622
  "COMBO_AUTOMATIC_DISABLED",
624
623
  "BROWSE_UNAVAILABLE"
625
624
  ],
@@ -709,7 +708,6 @@ export const operationErrors = {
709
708
  "STATE_CONFLICT",
710
709
  "COMBO_AUTOMATIC_DISABLED",
711
710
  "FINANCIAL_ACTIONS_DISABLED",
712
- "GAS_PRICE_ABOVE_CEILING",
713
711
  "ORIGIN_REQUIRED"
714
712
  ],
715
713
  "createRunOffClaim": [
@@ -3573,7 +3573,7 @@ export type components = {
3573
3573
  readonly floor_bps: number | null;
3574
3574
  /** @description SHA-256 of the exact pinned artifact that names this deployment's chain and vault: the release artifact on chain 999, the environment's deployment manifest on 998. A client compares it with its own pinned artifact to bind the read to its deployment. */
3575
3575
  readonly deployment_digest: string;
3576
- /** @description Decisions for MAKER_WITHDRAW and MAKER_QUOTE on the MAKER_VAULT route. MAKER_WITHDRAW is the amount a new withdrawal request may ask for: free_after_pending, so it never takes collateral from fills already admitted. The vault re-checks free collateral when the request executes after its delay; it is null with MAKER_WITHDRAW_PENDING while a request is live, or with a reconciliation blocker. MAKER_QUOTE is always null with one blocker, because quoting capacity depends on state only the maker's bot holds, such as its other live quotes. PRIVATE_QUOTE_CAPACITY_UNAVAILABLE means only that Totalis cannot compute that amount; it does not mean quoting is off, and the maker can keep quoting. A reconciliation blocker replaces it while the vault read and venue records disagree. */
3576
+ /** @description Decisions for MAKER_WITHDRAW and MAKER_QUOTE on the MAKER_VAULT route. MAKER_WITHDRAW is the amount a new withdrawal request may ask for: free_after_pending, so it never takes collateral from fills already admitted. The vault re-checks free collateral when the request executes after its delay; it is null with MAKER_WITHDRAW_PENDING while a request is live, or with a reconciliation blocker. MAKER_QUOTE is the most new quotes may promise: free_after_pending less a live v1 withdrawal request's amount, never below zero. Quotes reserve nothing, so it does not count the maker's other live quotes; if several are accepted at once, a confirm past it fails QUOTE_CAPACITY_EXCEEDED. Both are null with a reconciliation blocker while the vault read and venue records disagree. */
3577
3577
  readonly actions: readonly components["schemas"]["ActionAvailability"][];
3578
3578
  /** @description Venue reservations on MAKER_VAULT that make up pending_commitments. */
3579
3579
  readonly reservations: readonly components["schemas"]["Reservation"][];
@@ -578,6 +578,24 @@ export type components = {
578
578
  readonly publication_freshness?: boolean;
579
579
  /** @description Opt in to scoreboards frames: the live game scoreboard of every game with a selected outcome, complete after each snapshot, then on every change. Without it the socket gets no scoreboards frame. */
580
580
  readonly scoreboards?: boolean;
581
+ /** @description Opt in to network frames: the HyperEVM gas price against the level Totalis accepts quotes at, after each snapshot, then on every change the app acts on. Without it the socket gets no network frame. */
582
+ readonly network?: boolean;
583
+ };
584
+ readonly MarketNetworkFrame: {
585
+ /**
586
+ * @description Frame discriminator, always network.
587
+ * @constant
588
+ */
589
+ readonly channel: "network";
590
+ /** @description The network state. One frame carries all of it; replace the local state with it. */
591
+ readonly data: {
592
+ /** @description The HyperEVM network gas price (eth_gasPrice, the next small block's base fee) in wei, as of when the frame was sent; null when it cannot be read. Accepting a quote (entry, cash-out or golden placement) is refused with GAS_PRICE_ABOVE_CEILING while it is above accept_below_wei. */
593
+ readonly gas_price_wei: components["schemas"]["Uint"] | null;
594
+ /** @description The highest gas price in wei at which Totalis accepts quotes, at that price included; null when unknown. RFQs and quotes keep flowing above it. */
595
+ readonly accept_below_wei: components["schemas"]["Uint"] | null;
596
+ /** @description The highest gas price in wei since the price last went above accept_below_wei; set exactly while gas_price_wei is above it, null otherwise and while the price cannot be read. */
597
+ readonly peak_wei: components["schemas"]["Uint"] | null;
598
+ };
581
599
  };
582
600
  readonly MarketScoreboardsFrame: {
583
601
  /**
@@ -1080,7 +1098,7 @@ export type components = {
1080
1098
  readonly floor_bps: number | null;
1081
1099
  /** @description SHA-256 of the exact pinned artifact that names this deployment's chain and vault: the release artifact on chain 999, the environment's deployment manifest on 998. A client compares it with its own pinned artifact to bind the read to its deployment. */
1082
1100
  readonly deployment_digest: string;
1083
- /** @description Decisions for MAKER_WITHDRAW and MAKER_QUOTE on the MAKER_VAULT route. MAKER_WITHDRAW is the amount a new withdrawal request may ask for: free_after_pending, so it never takes collateral from fills already admitted. The vault re-checks free collateral when the request executes after its delay; it is null with MAKER_WITHDRAW_PENDING while a request is live, or with a reconciliation blocker. MAKER_QUOTE is always null with one blocker, because quoting capacity depends on state only the maker's bot holds, such as its other live quotes. PRIVATE_QUOTE_CAPACITY_UNAVAILABLE means only that Totalis cannot compute that amount; it does not mean quoting is off, and the maker can keep quoting. A reconciliation blocker replaces it while the vault read and venue records disagree. */
1101
+ /** @description Decisions for MAKER_WITHDRAW and MAKER_QUOTE on the MAKER_VAULT route. MAKER_WITHDRAW is the amount a new withdrawal request may ask for: free_after_pending, so it never takes collateral from fills already admitted. The vault re-checks free collateral when the request executes after its delay; it is null with MAKER_WITHDRAW_PENDING while a request is live, or with a reconciliation blocker. MAKER_QUOTE is the most new quotes may promise: free_after_pending less a live v1 withdrawal request's amount, never below zero. Quotes reserve nothing, so it does not count the maker's other live quotes; if several are accepted at once, a confirm past it fails QUOTE_CAPACITY_EXCEEDED. Both are null with a reconciliation blocker while the vault read and venue records disagree. */
1084
1102
  readonly actions: readonly components["schemas"]["ActionAvailability"][];
1085
1103
  /** @description Venue reservations on MAKER_VAULT that make up pending_commitments. */
1086
1104
  readonly reservations: readonly components["schemas"]["Reservation"][];
@@ -1096,6 +1114,8 @@ export type components = {
1096
1114
  /** @description Stream cursor the client asked to resume after; null when it started without one. */
1097
1115
  readonly cursor: components["schemas"]["Cursor"] | null;
1098
1116
  };
1117
+ /** Format: uint256-decimal */
1118
+ readonly Uint: string;
1099
1119
  readonly ScoreboardCompetitor: {
1100
1120
  /** @description The participant's name as our catalog spells it, cut to 96 characters ending in an ellipsis when longer. */
1101
1121
  readonly name: string;
@@ -1370,8 +1390,6 @@ export type components = {
1370
1390
  readonly reason: "UNQUALIFIED_MARKET_CLASS" | "MISSING_STRUCTURED_SOURCE" | "AMBIGUOUS_DESCRIPTION" | "UNSUPPORTED_PROTOCOL_VERSION";
1371
1391
  };
1372
1392
  readonly "$defs-Deadline": components["schemas"]["$defs-DeadlineAvailable"] | components["schemas"]["$defs-DeadlineUnavailable"];
1373
- /** Format: uint256-decimal */
1374
- readonly Uint: string;
1375
1393
  readonly PublicationCatalogSide: {
1376
1394
  /** @description Market side, YES or NO. */
1377
1395
  readonly side: components["schemas"]["Side"];
@@ -1,12 +1,12 @@
1
- export declare const sdkVersion = "208.0.0-golden-combo";
2
- export declare const openapiSha256 = "d20296ea5f9a68f36dfe34c735d7cac2a5b5e2a0d116f0bb183c1e7f192601ff";
3
- export declare const realtimeSha256 = "1cac740e108e84ad1979f6ccc71089efd840404cb72d1612a86edc02769637e3";
1
+ export declare const sdkVersion = "209.0.0-gas-at-accept";
2
+ export declare const openapiSha256 = "0eaeaf098c1a1c14ede94a521a2b63db7954b6fc8f61acb54a4b1feed5d9e2dc";
3
+ export declare const realtimeSha256 = "f4f1078418b5302417babe1380b85b0c4f89cb0fdfaff3a46154dd2018625c07";
4
4
  export declare const jsonSchemaSha256: {
5
5
  readonly "account.schema.json": "5106e2d53abef190990eff113f6692dd27df5848439cf5a80a42c11e89f2bef6";
6
6
  readonly "comments.schema.json": "18f4addcfa4e31c2c833fce8b8beca61d2e2ee5b6318c2ed0b479698ff56b65e";
7
7
  readonly "common.schema.json": "04f51deb3cbea448e59195e26ede3212598d58a7940fe67eb2123fd9161c5edb";
8
8
  readonly "core-exit.schema.json": "c7f617e815225cdcac95c236f8b73fbe288ee5713ff444c3be90eb915fc3a401";
9
- readonly "error.schema.json": "724f7e86716a49effe27694ca8fd8370d6f215798d3f663362f1718fd89e7ebb";
9
+ readonly "error.schema.json": "d15dad1b8369b45746271e0fddd2106535c22493668b703544c9ddfa80761012";
10
10
  readonly "hypercore.schema.json": "5b89b2bbff7ec8cc1b8717375d12ce9cd5ab6aa5af03c4fdc6cc753ef9583a2c";
11
11
  readonly "identity.schema.json": "94534b768030736f4fd1fad285f1312454ca5fbff0b1eb5fab70416a78923bd0";
12
12
  readonly "maker-access.schema.json": "49698ee0235e42064aae0397db1e0f646bdc10d9dfa10121714ba06dd69fee3b";
@@ -15,7 +15,7 @@ export declare const jsonSchemaSha256: {
15
15
  readonly "market-data.schema.json": "85db33fac6a29b0fa87a500bfda947d0ab3913b13f1c26663d4a7c0484c35786";
16
16
  readonly "product-metadata.schema.json": "7c8ffbde878a0aedaed16814fcfd2e80038054b140886cc8736bb7b508042631";
17
17
  readonly "quote.schema.json": "5616260d399d022bde2d0130cc9f8a09f71a3dc877276adf796c7a174d21b59a";
18
- readonly "realtime.schema.json": "1cac740e108e84ad1979f6ccc71089efd840404cb72d1612a86edc02769637e3";
18
+ readonly "realtime.schema.json": "f4f1078418b5302417babe1380b85b0c4f89cb0fdfaff3a46154dd2018625c07";
19
19
  };
20
20
  export declare const operations: {
21
21
  readonly client: readonly ["abandonCoreExit", "acceptQuote", "activeCoreExits", "admitOwnMaker", "admitPartnerWallet", "bindEmbeddedWallet", "cancelRfq", "confirmComboCopyAgent", "confirmCoreCopyAgent", "createCashout", "createComment", "createCoreExit", "createDeposit", "createGoldenRfq", "createRfq", "createRunOffClaim", "createWalletChallenge", "createWalletSession", "createWithdrawal", "deleteComment", "editComment", "endWalletSession", "followTrader", "getAcceptance", "getAccountActivity", "getAccountPnl", "getAccountPosition", "getBalances", "getCopyAgents", "getCopyBudget", "getCopySettings", "getCopySummary", "getCoreExit", "getDeployment", "getGolden", "getGoldenMarkets", "getGoldenOffer", "getGoldenSuggestions", "getHypercoreBalance", "getHypercorePortfolio", "getHypercoreSettlementCredits", "getIdentity", "getMakerActivity", "getMakerCapital", "getMakerExposure", "getMakerPerformance", "getMakerPosition", "getMakerQuotes", "getMakerTelemetry", "getMakerVaultFundingTransaction", "getMakerWithdrawal", "getMarket", "getMarketDataConfig", "getMarketDefinitions", "getMarketHistory", "getMarketRecurringRound", "getMarketReferenceCloses", "getMarketScoreTimeline", "getMarketStats", "getOperation", "getOwnMaker", "getPartnerReport", "getPerpMarks", "getProfitLeaderboard", "getQuestion", "getQuestionRecurringRound", "getQuestionScoreTimeline", "getRfq", "getSeries", "getSuggestedCombo", "getTaxonomy", "getTrader", "getTraderPnl", "getUsernameAvailability", "getVaultAgents", "getVolumeLeaderboard", "getWithdrawal", "grantComboCopyAgent", "grantVaultAgent", "likeComment", "listAccountActivity", "listAccountPositions", "listComboCopies", "listComboFeed", "listCommentReplies", "listComments", "listControlledMakers", "listCopiedFills", "listCopyTrades", "listDiscovery", "listFollows", "listMakerActivity", "listMakerPositions", "listMakerQuoteHistory", "listMarkets", "listOperations", "listQuotes", "listTraderPositions", "listTraderTrades", "placeGolden", "reactComment", "recordAcquisition", "refreshPicture", "requestComboCopyAgent", "requestCoreCopyAgent", "revokeComboCopyAgent", "searchCatalog", "setAvatar", "setCopyAllocation", "setCopySettings", "setPublicProfile", "setUsername", "stream", "streamMarkets", "switchOffComboCopyAgent", "switchOffCoreCopyAgent", "unfollowTrader", "unlikeComment", "unreactComment"];
@@ -1,13 +1,13 @@
1
1
  // Generated by scripts/generate.mjs; do not edit.
2
- export const sdkVersion = "208.0.0-golden-combo";
3
- export const openapiSha256 = "d20296ea5f9a68f36dfe34c735d7cac2a5b5e2a0d116f0bb183c1e7f192601ff";
4
- export const realtimeSha256 = "1cac740e108e84ad1979f6ccc71089efd840404cb72d1612a86edc02769637e3";
2
+ export const sdkVersion = "209.0.0-gas-at-accept";
3
+ export const openapiSha256 = "0eaeaf098c1a1c14ede94a521a2b63db7954b6fc8f61acb54a4b1feed5d9e2dc";
4
+ export const realtimeSha256 = "f4f1078418b5302417babe1380b85b0c4f89cb0fdfaff3a46154dd2018625c07";
5
5
  export const jsonSchemaSha256 = {
6
6
  "account.schema.json": "5106e2d53abef190990eff113f6692dd27df5848439cf5a80a42c11e89f2bef6",
7
7
  "comments.schema.json": "18f4addcfa4e31c2c833fce8b8beca61d2e2ee5b6318c2ed0b479698ff56b65e",
8
8
  "common.schema.json": "04f51deb3cbea448e59195e26ede3212598d58a7940fe67eb2123fd9161c5edb",
9
9
  "core-exit.schema.json": "c7f617e815225cdcac95c236f8b73fbe288ee5713ff444c3be90eb915fc3a401",
10
- "error.schema.json": "724f7e86716a49effe27694ca8fd8370d6f215798d3f663362f1718fd89e7ebb",
10
+ "error.schema.json": "d15dad1b8369b45746271e0fddd2106535c22493668b703544c9ddfa80761012",
11
11
  "hypercore.schema.json": "5b89b2bbff7ec8cc1b8717375d12ce9cd5ab6aa5af03c4fdc6cc753ef9583a2c",
12
12
  "identity.schema.json": "94534b768030736f4fd1fad285f1312454ca5fbff0b1eb5fab70416a78923bd0",
13
13
  "maker-access.schema.json": "49698ee0235e42064aae0397db1e0f646bdc10d9dfa10121714ba06dd69fee3b",
@@ -16,7 +16,7 @@ export const jsonSchemaSha256 = {
16
16
  "market-data.schema.json": "85db33fac6a29b0fa87a500bfda947d0ab3913b13f1c26663d4a7c0484c35786",
17
17
  "product-metadata.schema.json": "7c8ffbde878a0aedaed16814fcfd2e80038054b140886cc8736bb7b508042631",
18
18
  "quote.schema.json": "5616260d399d022bde2d0130cc9f8a09f71a3dc877276adf796c7a174d21b59a",
19
- "realtime.schema.json": "1cac740e108e84ad1979f6ccc71089efd840404cb72d1612a86edc02769637e3"
19
+ "realtime.schema.json": "f4f1078418b5302417babe1380b85b0c4f89cb0fdfaff3a46154dd2018625c07"
20
20
  };
21
21
  export const operations = {
22
22
  "client": [
@@ -5,6 +5,7 @@ export type HyperliquidNetwork = {
5
5
  /** The signing domain chain the HyperEVM bridge names: the deployment's own chain. */
6
6
  readonly signatureChainId: Hex;
7
7
  readonly exchangeUrl: string;
8
+ readonly infoUrl: string;
8
9
  readonly usdcToken: string;
9
10
  };
10
11
  export declare function hyperliquidNetwork(chainId: string | number): HyperliquidNetwork;
@@ -109,3 +110,27 @@ export declare function settleHypercore(signed: SignedSendAsset, options?: {
109
110
  readonly now?: () => number;
110
111
  readonly retryDelayMs?: number;
111
112
  }): Promise<HypercoreAnswer>;
113
+ /** A read of Hyperliquid's `/info` on one network: the request body in, the answer's JSON out. */
114
+ export type HyperliquidInfo = (network: HyperliquidNetwork, body: Readonly<Record<string, unknown>>, signal?: AbortSignal) => Promise<unknown>;
115
+ /** POST to the network's `/info`. A non-2xx answer or a body that is not JSON throws. */
116
+ export declare function hyperliquidInfo(fetchImpl?: typeof fetch): HyperliquidInfo;
117
+ /** Hyperliquid's one-time account setup fee, in USDC base units, taken on top of an account's first send out when it was funded without paying it. */
118
+ export declare const coreSetupFee = 1000000n;
119
+ /** The account mode Hyperliquid's `userAbstraction` names; `null` for one this SDK does not know. */
120
+ export type CoreAccountMode = "STANDARD" | "UNIFIED" | "PORTFOLIO_MARGIN";
121
+ /**
122
+ * The account's HyperCore USDC as a Combo can bridge it, read from
123
+ * Hyperliquid. `spendable` is spot USDC `total` less `hold`, then floored
124
+ * to USDC base units (6 decimals); `hold` already carries order holds and
125
+ * position margin. A Portfolio Margin account offers none, as in the Totalis
126
+ * app. `setupFee` says whether a bridge from it also pays `coreSetupFee`; it is
127
+ * read only when there is something to bridge. Each is `null` when unread or
128
+ * unreadable, never 0.
129
+ */
130
+ export type CoreCash = {
131
+ readonly mode: CoreAccountMode | null;
132
+ readonly spendable: bigint | null;
133
+ readonly setupFee: boolean | null;
134
+ };
135
+ /** Read `account`'s `CoreCash` on `network`. A failed or malformed read leaves its fields `null`; it never throws. */
136
+ export declare function readCoreCash(network: HyperliquidNetwork, account: string, info?: HyperliquidInfo, signal?: AbortSignal): Promise<CoreCash>;
package/dist/hypercore.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { sleep } from "./request.js";
2
2
  import { canonicalSignature } from "./typed-data.js";
3
3
  const networks = {
4
- "999": { chain: "Mainnet", signatureChainId: "0x3e7", exchangeUrl: "https://api.hyperliquid.xyz/exchange", usdcToken: "USDC:0x6d1e7cde53ba9467b783cb7c530ce054" },
5
- "998": { chain: "Testnet", signatureChainId: "0x3e6", exchangeUrl: "https://api.hyperliquid-testnet.xyz/exchange", usdcToken: "USDC:0xeb62eee3685fc4c43992febcd9e75443" },
4
+ "999": { chain: "Mainnet", signatureChainId: "0x3e7", exchangeUrl: "https://api.hyperliquid.xyz/exchange", infoUrl: "https://api.hyperliquid.xyz/info", usdcToken: "USDC:0x6d1e7cde53ba9467b783cb7c530ce054" },
5
+ "998": { chain: "Testnet", signatureChainId: "0x3e6", exchangeUrl: "https://api.hyperliquid-testnet.xyz/exchange", infoUrl: "https://api.hyperliquid-testnet.xyz/info", usdcToken: "USDC:0xeb62eee3685fc4c43992febcd9e75443" },
6
6
  };
7
7
  export function hyperliquidNetwork(chainId) {
8
8
  const key = String(chainId);
@@ -130,3 +130,77 @@ export async function settleHypercore(signed, options = {}) {
130
130
  return { kind: "unknown" };
131
131
  }
132
132
  }
133
+ /** POST to the network's `/info`. A non-2xx answer or a body that is not JSON throws. */
134
+ export function hyperliquidInfo(fetchImpl = (input, init) => globalThis.fetch(input, init)) {
135
+ return async (network, body, signal) => {
136
+ const response = await fetchImpl(network.infoUrl, {
137
+ method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body),
138
+ ...(signal === undefined ? {} : { signal }),
139
+ });
140
+ if (!response.ok)
141
+ throw new Error(`Hyperliquid info answered ${response.status}`);
142
+ const answer = JSON.parse(await response.text());
143
+ return answer;
144
+ };
145
+ }
146
+ /** Hyperliquid's one-time account setup fee, in USDC base units, taken on top of an account's first send out when it was funded without paying it. */
147
+ export const coreSetupFee = 1000000n;
148
+ const decimalText = /^\d+(\.\d+)?$/;
149
+ const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
150
+ function coreMode(answer) {
151
+ if (answer === "default" || answer === "disabled")
152
+ return "STANDARD";
153
+ if (answer === "unifiedAccount")
154
+ return "UNIFIED";
155
+ if (answer === "portfolioMargin")
156
+ return "PORTFOLIO_MARGIN";
157
+ return null;
158
+ }
159
+ /** Spot decimal text (8 decimals) as integer units, or `null` past 8 decimals. */
160
+ function spotUnits(text) {
161
+ const [whole = "0", fraction = ""] = text.split(".");
162
+ return fraction.length > 8 ? null : BigInt(whole) * 100000000n + BigInt(fraction.padEnd(8, "0"));
163
+ }
164
+ /**
165
+ * Spot USDC `total` less `hold`, exact in spot's 8 decimals and only then
166
+ * floored to USDC base units, so the sub-unit parts never round it up.
167
+ * `null` when the answer is malformed: two USDC entries, or a hold above the
168
+ * total. An account with no USDC entry holds none.
169
+ */
170
+ function spotUsdc(answer) {
171
+ if (!record(answer) || !Array.isArray(answer.balances))
172
+ return null;
173
+ const entries = answer.balances.filter((entry) => record(entry) && entry.coin === "USDC");
174
+ if (entries.length === 0)
175
+ return 0n;
176
+ const [usdc] = entries;
177
+ if (entries.length > 1 || !record(usdc) || typeof usdc.total !== "string" || typeof usdc.hold !== "string" || !decimalText.test(usdc.total) || !decimalText.test(usdc.hold))
178
+ return null;
179
+ const total = spotUnits(usdc.total);
180
+ const hold = spotUnits(usdc.hold);
181
+ if (total === null || hold === null || hold > total)
182
+ return null;
183
+ return (total - hold) / 100n;
184
+ }
185
+ /** Whether `preTransferCheck` charges the setup fee: its `fee` is exactly 0 or exactly `coreSetupFee`; anything else is `null`. */
186
+ function setupFeeCharged(answer) {
187
+ if (!record(answer) || typeof answer.fee !== "string" || !decimalText.test(answer.fee))
188
+ return null;
189
+ const fee = spotUnits(answer.fee);
190
+ return fee === 0n ? false : fee === coreSetupFee * 100n ? true : null;
191
+ }
192
+ const settledValue = (result) => (result.status === "fulfilled" ? result.value : undefined);
193
+ /** Read `account`'s `CoreCash` on `network`. A failed or malformed read leaves its fields `null`; it never throws. */
194
+ export async function readCoreCash(network, account, info = hyperliquidInfo(), signal) {
195
+ const [modeRead, spotRead] = await Promise.allSettled([
196
+ info(network, { type: "userAbstraction", user: account }, signal),
197
+ info(network, { type: "spotClearinghouseState", user: account }, signal),
198
+ ]);
199
+ const mode = coreMode(settledValue(modeRead));
200
+ const spot = spotUsdc(settledValue(spotRead));
201
+ const spendable = mode === null || spot === null ? null : mode === "PORTFOLIO_MARGIN" ? 0n : spot;
202
+ if (spendable === null || spendable === 0n)
203
+ return { mode, spendable, setupFee: null };
204
+ const check = await info(network, { type: "preTransferCheck", user: hyperevmUsdcBridge, source: account }, signal).then(setupFeeCharged, () => null);
205
+ return { mode, spendable, setupFee: check };
206
+ }
package/dist/money.d.ts CHANGED
@@ -26,6 +26,24 @@ export declare function spendableCash(balance: Pick<Balance, "amount" | "state"
26
26
  readonly wallet: bigint | null;
27
27
  readonly total: bigint | null;
28
28
  };
29
+ /**
30
+ * The HyperCore USDC a Combo offers its bridge (`core` for `openPosition`,
31
+ * `signEntry` and `prepareEntryFunding`): all of `spendable`, less
32
+ * `coreSetupFee` when the bridge also pays it. `null` while either is unknown
33
+ * and there is Core to bridge.
34
+ */
35
+ export declare function offeredCore(spendable: bigint | null, setupFee: boolean | null): bigint | null;
36
+ /**
37
+ * The largest stake one Combo can take now, in USDC base units, as an entry
38
+ * plans its funding: free vault cash, then available wallet USDC, then a
39
+ * bridge of the offered Core less `bridgeGasBuffer`. `null` when any part is
40
+ * unknown, never a partial sum.
41
+ */
42
+ export declare function comboAllowance(cash: {
43
+ readonly vault: bigint | null;
44
+ readonly wallet: bigint | null;
45
+ readonly core: bigint | null;
46
+ }): bigint | null;
29
47
  /**
30
48
  * What the owner receives from a gross close amount (a settlement payout or a
31
49
  * sell-back price), as the vault pays it: the profit fee is
package/dist/money.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { bridgeGasBuffer, coreSetupFee } from "./hypercore.js";
1
2
  const bps = 10000n;
2
3
  /**
3
4
  * Spendable Totalis cash from `GET /v1/me/balances`, in USDC base units, as
@@ -25,6 +26,31 @@ export function spendableCash(balance) {
25
26
  total: balance.state === "CURRENT" && balance.amount !== null ? BigInt(balance.amount) : null,
26
27
  };
27
28
  }
29
+ /**
30
+ * The HyperCore USDC a Combo offers its bridge (`core` for `openPosition`,
31
+ * `signEntry` and `prepareEntryFunding`): all of `spendable`, less
32
+ * `coreSetupFee` when the bridge also pays it. `null` while either is unknown
33
+ * and there is Core to bridge.
34
+ */
35
+ export function offeredCore(spendable, setupFee) {
36
+ if (spendable === null || spendable === 0n || setupFee === false)
37
+ return spendable;
38
+ if (setupFee === null)
39
+ return null;
40
+ return spendable > coreSetupFee ? spendable - coreSetupFee : 0n;
41
+ }
42
+ /**
43
+ * The largest stake one Combo can take now, in USDC base units, as an entry
44
+ * plans its funding: free vault cash, then available wallet USDC, then a
45
+ * bridge of the offered Core less `bridgeGasBuffer`. `null` when any part is
46
+ * unknown, never a partial sum.
47
+ */
48
+ export function comboAllowance(cash) {
49
+ const { vault, wallet, core } = cash;
50
+ if (vault === null || wallet === null || core === null)
51
+ return null;
52
+ return vault + wallet + (core > bridgeGasBuffer ? core - bridgeGasBuffer : 0n);
53
+ }
28
54
  /**
29
55
  * What the owner receives from a gross close amount (a settlement payout or a
30
56
  * sell-back price), as the vault pays it: the profit fee is
package/dist/totalis.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { issueApiKey, rotateApiKey } from "./api-keys.js";
2
2
  import { type AccessToken, type ApiClientOptions, type PublicEnvironment } from "./base.js";
3
3
  import type { paths } from "./generated/client.js";
4
- import { type BridgedCash, type HypercoreAnswer, type HypercoreTransport, type SignedSendAsset } from "./hypercore.js";
4
+ import { type BridgedCash, type CoreAccountMode, type HypercoreAnswer, type HypercoreTransport, type HyperliquidInfo, type SignedSendAsset } from "./hypercore.js";
5
5
  import { BalanceUnknownError, EntryError, ExitUnavailableError } from "./flow-errors.js";
6
6
  import { ApiError, NetworkError, type RetryPolicy } from "./request.js";
7
7
  import { type SignerInput } from "./signer.js";
@@ -69,6 +69,23 @@ export type EntryCash = {
69
69
  readonly wallet: Amount | null;
70
70
  };
71
71
  export type DepositAccepted = Ok<"/v1/me/deposits", "post", 202>;
72
+ /**
73
+ * What one Combo can stake, from the venue balances and the account's
74
+ * HyperCore cash, in USDC base units (`readComboCash`). `vault` and `wallet`
75
+ * are `spendableCash`'s; `core` is HyperCore spot USDC less its hold;
76
+ * `setupFee` whether a bridge from it pays Hyperliquid's one-time setup fee;
77
+ * `offeredCore` what an entry may bridge (`offeredCore`); `allowance` the
78
+ * largest stake (`comboAllowance`). Each is `null` when unknown, never 0.
79
+ */
80
+ export type ComboCash = {
81
+ readonly vault: bigint | null;
82
+ readonly wallet: bigint | null;
83
+ readonly coreMode: CoreAccountMode | null;
84
+ readonly core: bigint | null;
85
+ readonly setupFee: boolean | null;
86
+ readonly offeredCore: bigint | null;
87
+ readonly allowance: bigint | null;
88
+ };
72
89
  /** Who signed an acceptance record, and for which vault; a record is only sent or recovered by the same account on the same deployment. */
73
90
  type RecordScope = {
74
91
  readonly acceptanceId: string;
@@ -263,6 +280,10 @@ export declare function createTotalis(options: TotalisOptions): {
263
280
  readonly wallet: bigint | null;
264
281
  readonly total: bigint | null;
265
282
  }>;
283
+ readComboCash: (options?: {
284
+ readonly info?: HyperliquidInfo;
285
+ readonly signal?: AbortSignal;
286
+ }) => Promise<ComboCash>;
266
287
  openPosition: (request: {
267
288
  readonly legs: readonly Leg[];
268
289
  readonly stake: Amount;
package/dist/totalis.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { keccak_256 } from "@noble/hashes/sha3";
2
2
  import { createApiKeyClient, issueApiKey, rotateApiKey } from "./api-keys.js";
3
3
  import { audienceClient, headerRecord } from "./base.js";
4
- import { bridgeAction, bridgeGasBuffer, hyperliquidExchange, hyperliquidNetwork, settleHypercore, signSendAsset, usdcUnits, } from "./hypercore.js";
4
+ import { bridgeAction, bridgeGasBuffer, hyperliquidExchange, hyperliquidNetwork, readCoreCash, settleHypercore, signSendAsset, usdcUnits, } from "./hypercore.js";
5
5
  import { BalanceUnknownError, EntryError, ExitUnavailableError, normalizeError } from "./flow-errors.js";
6
- import { spendableCash } from "./money.js";
6
+ import { comboAllowance, offeredCore, spendableCash } from "./money.js";
7
7
  import { ApiError, backoffDelay, envelope, NetworkError, randomBytes32, resendable, retryingFetch, sendOnce, singleFetch, sleep, unwrap, uuidv7 } from "./request.js";
8
8
  import { toTotalisSigner } from "./signer.js";
9
9
  import { TotalisStream } from "./stream.js";
@@ -433,6 +433,26 @@ export function createTotalis(options) {
433
433
  async function readSpendableCash(signal) {
434
434
  return spendableCash(unwrap(await client.GET("/v1/me/balances", signal === undefined ? {} : { signal })));
435
435
  }
436
+ /**
437
+ * The account's Combo cash now (`ComboCash`): one venue balances read and
438
+ * the signer's HyperCore cash read from Hyperliquid, together. Pass `cash`
439
+ * and `offeredCore` straight to `openPosition` (`cash`, `core`) so the entry
440
+ * plans from what was shown. A failed HyperCore read leaves its fields
441
+ * `null`; a failed balances read throws, as `spendableCash` does. `info`
442
+ * replaces the Hyperliquid read, for tests or a proxy.
443
+ */
444
+ async function readComboCash(options = {}) {
445
+ const [account, chain] = await Promise.all([(async () => (await requireSigner()).address())(), deployment()]);
446
+ const [venue, core] = await Promise.all([
447
+ readSpendableCash(options.signal),
448
+ readCoreCash(hyperliquidNetwork(chain.chain_id), account, options.info, options.signal),
449
+ ]);
450
+ const offered = offeredCore(core.spendable, core.setupFee);
451
+ return {
452
+ vault: venue.vault, wallet: venue.wallet, coreMode: core.mode, core: core.spendable, setupFee: core.setupFee,
453
+ offeredCore: offered, allowance: comboAllowance({ vault: venue.vault, wallet: venue.wallet, core: offered }),
454
+ };
455
+ }
436
456
  /** The wallet's USDC authorization of `value` into the vault; the venue fills `account` and `from` with the same wallet. */
437
457
  async function depositAuthorization(chain, account, value) {
438
458
  const authorization = { value: value.toString(), valid_after: String(now() - 60), valid_before: String(now() + 600), salt: randomBytes32() };
@@ -1360,6 +1380,7 @@ export function createTotalis(options) {
1360
1380
  deployment,
1361
1381
  /** Spendable Totalis cash from a fresh balances read (`spendableCash`): `{ vault, wallet, total }`, each `null` while unknown, never 0. */
1362
1382
  spendableCash: readSpendableCash,
1383
+ readComboCash,
1363
1384
  openPosition,
1364
1385
  cashOut,
1365
1386
  prepareEntryFunding,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totalis/hip4-client",
3
- "version": "0.80.0",
3
+ "version": "0.82.0",
4
4
  "description": "Totalis HIP-4 SDK: typed HTTP clients, signer-agnostic typed data, a retrying request layer, pagination, a realtime stream and taker/maker flows",
5
5
  "type": "module",
6
6
  "files": [