@syldel/hl-shared-types 0.0.23 → 0.0.24
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/README.md +38 -0
- package/dist/interfaces/perp/balance.interfaces.d.ts +6 -0
- package/dist/interfaces/perp/funding.interfaces.d.ts +115 -0
- package/dist/interfaces/perp/funding.interfaces.js +2 -0
- package/dist/interfaces/perp/index.d.ts +1 -0
- package/dist/interfaces/perp/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -119,10 +119,48 @@ git push origin main --follow-tags
|
|
|
119
119
|
|
|
120
120
|
---
|
|
121
121
|
|
|
122
|
+
## 🔍 Avant de déclarer un champ : d'où vient l'information
|
|
123
|
+
|
|
124
|
+
Chaque champ de ce paquet est une **affirmation sur ce que l'exchange rend**, et les trois
|
|
125
|
+
dépôts la croient. Une affirmation fausse ne se voit pas : elle se paie plus loin, sur un
|
|
126
|
+
dimensionnement ou un affichage. Avant d'ajouter, de resserrer ou d'élargir un type, lire
|
|
127
|
+
[`nest-hyperliquid-gateway/docs/sources.md`](https://github.com/Syldel/nest-hyperliquid-gateway/blob/main/docs/sources.md).
|
|
128
|
+
|
|
129
|
+
En résumé de ce document :
|
|
130
|
+
|
|
131
|
+
* **La mesure** (captures du gateway, lectures `/hyperliquid/info/*`) prouve qu'une forme
|
|
132
|
+
existe, jamais qu'elle soit la seule. Un `null` vu une fois clôt la nullité d'un champ ;
|
|
133
|
+
mille valeurs présentes ne closent rien. Et un échantillon se décrit honnêtement — 22
|
|
134
|
+
instantanés d'une même position ne sont pas 22 observations.
|
|
135
|
+
* **La doc officielle** fait autorité sur les noms, et tient sur **un exemple par
|
|
136
|
+
endpoint** : elle est donc muette sur ce qui varie. Un champ absent d'un exemple n'est ni
|
|
137
|
+
absent de l'API ni optionnel.
|
|
138
|
+
* **Le SDK Python officiel**
|
|
139
|
+
([hyperliquid-dex/hyperliquid-python-sdk](https://github.com/hyperliquid-dex/hyperliquid-python-sdk))
|
|
140
|
+
est de première partie **et typé** : il tranche les unions, les champs propres à une
|
|
141
|
+
variante et les valeurs énumérées que la prose laisse en suspens. Mais il ne type pas
|
|
142
|
+
tout, et son silence n'est pas une réponse.
|
|
143
|
+
* **Les SDK communautaires ne concluent pas.** La page d'API en recommande plusieurs — un en
|
|
144
|
+
Rust, deux en TypeScript, plus CCXT — et le dit : ils sont écrits par la communauté. Être
|
|
145
|
+
lié par la doc officielle donne de la visibilité, pas de l'autorité ; ils lisent la même
|
|
146
|
+
API que nous et peuvent s'être trompés pareil. Ils servent à repérer une question, jamais
|
|
147
|
+
à la clore — et le piège est celui en TypeScript, dont on a envie de recopier une union
|
|
148
|
+
toute faite. Il n'existe **aucun SDK TypeScript de première partie**.
|
|
149
|
+
|
|
150
|
+
`HLPerpLeverage` est le cas d'école : ni les captures (que du `cross`) ni l'exemple de la
|
|
151
|
+
doc (que de l'`isolated`) ne pouvaient trancher, et `hyperliquid/utils/types.py` déclare les
|
|
152
|
+
deux branches. Les types portent leur source et leur date en commentaire — c'est ce qui
|
|
153
|
+
permet de les contredire plus tard au lieu de devoir tout remesurer.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
122
157
|
## 📝 Conventions de code
|
|
123
158
|
|
|
124
159
|
* **Sauts de ligne** : Une ligne vide est automatiquement insérée entre chaque `interface` pour une meilleure lisibilité.
|
|
125
160
|
* **Naming** : Toutes les interfaces commencent par `HL`.
|
|
126
161
|
* **Types stricts** : Usage de `DecimalString` pour la précision financière.
|
|
162
|
+
* **Fins de ligne** : LF partout, imposé par `.gitattributes` et non par la configuration de
|
|
163
|
+
la machine — le paquet publié embarque du code généré par `tsc`, dont les fins de ligne
|
|
164
|
+
suivent celles des sources.
|
|
127
165
|
|
|
128
166
|
---
|
|
@@ -25,6 +25,12 @@ import { DecimalString, Timestamp } from '../common';
|
|
|
25
25
|
* porte `rawUsd: "-95.059824"`. Aucun des deux ne couvre l'autre branche — le
|
|
26
26
|
* SDK, lui, les couvre toutes les deux.
|
|
27
27
|
*
|
|
28
|
+
* ⚠️ Ce « officiel » ne se déduit **pas** du nom de l'organisation GitHub, qui
|
|
29
|
+
* n'est d'ailleurs pas vérifiée (`is_verified: false`). Il repose sur la page
|
|
30
|
+
* d'API de la documentation, qui distingue ce SDK des bibliothèques
|
|
31
|
+
* communautaires, et sur PyPI, qui le publie sous `hello@hyperliquid.xyz`. La
|
|
32
|
+
* chaîne et ses limites : `nest-hyperliquid-gateway/docs/sources.md`.
|
|
33
|
+
*
|
|
28
34
|
* Pourquoi l'union et non `rawUsd?: DecimalString` : l'optionnel rendrait
|
|
29
35
|
* `lev.rawUsd` lisible sans vérifier `type`, et `Number(undefined)` rend `NaN`
|
|
30
36
|
* sans un mot. L'union en fait une erreur de compilation. Et si un cross
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { DecimalString, Timestamp } from '../common';
|
|
2
|
+
/**
|
|
3
|
+
* ============================================================================
|
|
4
|
+
* L'HISTORIQUE DE FUNDING — LE SEUL CHAMP DE CONTEXTE QUI AIT UNE VRAIE SÉRIE
|
|
5
|
+
*
|
|
6
|
+
* `fundingHistory` est, au 2026-10-06, le **seul** endpoint d'information qui
|
|
7
|
+
* rende une série temporelle d'un champ de contexte de marché. Il n'existe
|
|
8
|
+
* aucun endpoint documenté pour l'historique de l'intérêt ouvert, ni pour celui
|
|
9
|
+
* des prix d'impact : ces valeurs ne sont lisibles qu'à l'instant courant.
|
|
10
|
+
*
|
|
11
|
+
* C'est ce qui décide de ce qu'un moteur de règles peut en faire : une
|
|
12
|
+
* transformation glissante (z-score, pente, percentile) a besoin d'une série,
|
|
13
|
+
* donc elle n'est légitime que sur `fundingRate` et `premium`.
|
|
14
|
+
*
|
|
15
|
+
* ## Ce qui a été mesuré, le 2026-10-06
|
|
16
|
+
*
|
|
17
|
+
* Deux appels, sur six heures, sur `api.hyperliquid.xyz` :
|
|
18
|
+
*
|
|
19
|
+
* - **BTC** (vivant) : 6 entrées pour 6 heures — la cadence est bien horaire,
|
|
20
|
+
* ce que la documentation confirme (« funding is paid every hour at one
|
|
21
|
+
* eighth of the computed rate »). Quatre clés, toutes en chaîne sauf `time`.
|
|
22
|
+
* **Aucun nul**, sur aucun champ.
|
|
23
|
+
* - **MATIC** (délisté) : 6 entrées également, avec `fundingRate: "0.0"` et
|
|
24
|
+
* `premium: "0.0"`.
|
|
25
|
+
* - **xyz:XYZ100** (HIP-3, vivant) : 6 entrées, écarts de 3 600 000 ms ± 20 ms,
|
|
26
|
+
* et le `coin` rendu est identique à celui demandé, préfixe compris.
|
|
27
|
+
*
|
|
28
|
+
* ⚠️ Les horodatages ne tombent **pas exactement** sur l'heure : les restes
|
|
29
|
+
* modulo une heure relevés valaient 37, 39, 27, 7, 46 et 24 ms. Aligner une
|
|
30
|
+
* fenêtre de requête sur l'heure pleine reste correct — `startTime` est
|
|
31
|
+
* inclusif, donc arrondir vers le bas attrape l'entrée — mais comparer un
|
|
32
|
+
* horodatage à une frontière d'heure par égalité ne marcherait pas.
|
|
33
|
+
*
|
|
34
|
+
* ## ⚠️ Trois pièges que ces mesures révèlent
|
|
35
|
+
*
|
|
36
|
+
* **1. `"0.0"` a trois significations différentes, et rien ne les distingue
|
|
37
|
+
* dans cette réponse.** Mesuré le 2026-10-06 via `perpDexs` :
|
|
38
|
+
*
|
|
39
|
+
* - un **marché délisté** rend `"0.0"` (MATIC) ;
|
|
40
|
+
* - un **marché vivant et sain** peut rendre `"0.0"` en permanence, parce que
|
|
41
|
+
* son dex déclare un multiplicateur de funding nul : `assetToFundingMultiplier`
|
|
42
|
+
* vaut `0.0` sur **tous** les actifs de `flx` et de `vntl` ;
|
|
43
|
+
* - et un financement réellement nul à cette heure-là.
|
|
44
|
+
*
|
|
45
|
+
* Une règle du genre `funding <= 0` serait donc vraie en permanence sur des
|
|
46
|
+
* marchés parfaitement vivants. Un consommateur doit croiser cette série avec
|
|
47
|
+
* `isDelisted` (voir `HLPerpMarketInfo`) **et** avec le multiplicateur du dex
|
|
48
|
+
* (voir `HLPerpDex.assetToFundingMultiplier`). L'API fournit ici elle-même la
|
|
49
|
+
* valeur de repli plausible et fausse que ce dépôt refuse d'habitude de
|
|
50
|
+
* fabriquer.
|
|
51
|
+
*
|
|
52
|
+
* **2. Un seuil de funding absolu n'est pas transposable d'un marché à
|
|
53
|
+
* l'autre.** Les multiplicateurs relevés vont de `0.0` (`flx`, `vntl`) à
|
|
54
|
+
* `0.000001` (`cash`), `0.01` à `1.0` (`hyna`, qui les fait varier **par
|
|
55
|
+
* actif** dans un même dex), `0.1` à `0.6` (`para`), `0.125` à `0.5` (`io`),
|
|
56
|
+
* `0.5` partout sur `xyz`. Trois dex n'en déclarent aucun. Un `funding >
|
|
57
|
+
* 0.00001` serait donc courant sur l'un et impossible sur l'autre : ce champ
|
|
58
|
+
* se compare **relativement** (z-score, percentile) ou normalisé par le
|
|
59
|
+
* multiplicateur, jamais à une constante écrite en dur.
|
|
60
|
+
*
|
|
61
|
+
* **3. `fundingRate` est souvent constant.** Sur BTC, les trois heures relevées
|
|
62
|
+
* valaient toutes `0.0000125`, soit exactement le plancher (un huitième de
|
|
63
|
+
* 0,01 %) ; sur `xyz:XYZ100`, toutes `0.00000625`, soit ce même plancher
|
|
64
|
+
* multiplié par le `0.5` du dex. Une transformation glissante sur un taux au
|
|
65
|
+
* plancher voit une série plate : son écart-type est nul, et un z-score n'y a
|
|
66
|
+
* aucun sens. `premium`, lui, varie en continu sur les deux marchés — c'est la
|
|
67
|
+
* série informative des deux.
|
|
68
|
+
*
|
|
69
|
+
* ## `premium` ici n'est pas `premium` dans `metaAndAssetCtxs`
|
|
70
|
+
*
|
|
71
|
+
* La documentation dit que « the premium is sampled **every 5 seconds and
|
|
72
|
+
* averaged over the hour** », et que `premium = impact_price_difference /
|
|
73
|
+
* oracle_price`. Le champ rendu ici est donc une **moyenne horaire** sur
|
|
74
|
+
* environ 720 échantillons, là où le `premium` d'un contexte d'actif est la
|
|
75
|
+
* lecture de l'instant. Les deux portent le même nom et ne sont pas la même
|
|
76
|
+
* quantité.
|
|
77
|
+
* ============================================================================
|
|
78
|
+
*/
|
|
79
|
+
/**
|
|
80
|
+
* Une entrée de l'historique de funding, telle que `fundingHistory` la rend.
|
|
81
|
+
*
|
|
82
|
+
* Aucun champ n'est optionnel ni nullable : mesuré sur un marché vivant **et**
|
|
83
|
+
* sur un marché délisté, l'endpoint rend toujours les quatre, et rend `"0.0"`
|
|
84
|
+
* plutôt que `null` quand il n'y a rien à payer.
|
|
85
|
+
*/
|
|
86
|
+
export interface HLFundingHistoryEntry {
|
|
87
|
+
/** Le marché concerné, tel que demandé (ex. `BTC`, `xyz:XYZ100`). */
|
|
88
|
+
coin: string;
|
|
89
|
+
/**
|
|
90
|
+
* Le taux **horaire** réellement appliqué, soit un huitième du taux calculé
|
|
91
|
+
* sur 8 heures. `"0.0"` sur un marché délisté — voir l'en-tête.
|
|
92
|
+
*/
|
|
93
|
+
fundingRate: DecimalString;
|
|
94
|
+
/**
|
|
95
|
+
* La prime moyenne de l'heure : `impact_price_difference / oracle_price`,
|
|
96
|
+
* échantillonnée toutes les 5 secondes et moyennée. Peut être négative.
|
|
97
|
+
*/
|
|
98
|
+
premium: DecimalString;
|
|
99
|
+
/** Début de l'heure de funding, en millisecondes. */
|
|
100
|
+
time: Timestamp;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Les paramètres de `fundingHistory`.
|
|
104
|
+
*
|
|
105
|
+
* ⚠️ À plat dans le corps de la requête, contrairement à `candleSnapshot` qui
|
|
106
|
+
* imbrique les siens sous une clé `req`. Deux endpoints voisins, deux formes :
|
|
107
|
+
* c'est le genre d'écart qui se découvre par un appel qui échoue.
|
|
108
|
+
*/
|
|
109
|
+
export interface HLFundingHistoryRequest {
|
|
110
|
+
coin: string;
|
|
111
|
+
/** Inclusif, en millisecondes. Requis. */
|
|
112
|
+
startTime: Timestamp;
|
|
113
|
+
/** Inclusif. Par défaut, l'instant courant. */
|
|
114
|
+
endTime?: Timestamp;
|
|
115
|
+
}
|
|
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./balance.interfaces"), exports);
|
|
18
18
|
__exportStar(require("./meta.interfaces"), exports);
|
|
19
19
|
__exportStar(require("./dexs.interfaces"), exports);
|
|
20
|
+
__exportStar(require("./funding.interfaces"), exports);
|