@totalis/hip4-client 0.80.0 → 0.81.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 +17 -0
- package/dist/client.d.ts +3 -3
- package/dist/client.js +2 -2
- package/dist/hypercore.d.ts +25 -0
- package/dist/hypercore.js +76 -2
- package/dist/money.d.ts +18 -0
- package/dist/money.js +26 -0
- package/dist/totalis.d.ts +22 -1
- package/dist/totalis.js +23 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
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.81.0
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- `totalis.readComboCash()`: what one Combo can stake now, from one
|
|
11
|
+
`GET /v1/me/balances` read and the signer's HyperCore cash read from
|
|
12
|
+
Hyperliquid (TT-2572). It answers `vault`, `wallet`, `core` (spot USDC less
|
|
13
|
+
its hold), `coreMode`, `setupFee`, `offeredCore` and `allowance`, each `null`
|
|
14
|
+
when unknown. Pass it as `cash` and `offeredCore` as `core` to `openPosition`,
|
|
15
|
+
`signEntry` or `prepareEntryFunding`; `allowance` is the largest stake they
|
|
16
|
+
plan from it. A Portfolio Margin account offers no Core, as in the Totalis app.
|
|
17
|
+
- `offeredCore(spendable, setupFee)` and `comboAllowance({ vault, wallet, core })`,
|
|
18
|
+
the same rule as plain functions.
|
|
19
|
+
- `readCoreCash(network, account, info?)`, `hyperliquidInfo(fetch?)`,
|
|
20
|
+
`coreSetupFee` and `infoUrl` on `hyperliquidNetwork`, for reading HyperCore
|
|
21
|
+
cash yourself.
|
|
22
|
+
|
|
6
23
|
## 0.80.0
|
|
7
24
|
|
|
8
25
|
### 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";
|
package/dist/hypercore.d.ts
CHANGED
|
@@ -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.
|
|
3
|
+
"version": "0.81.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": [
|