@syldel/hl-shared-types 0.0.27 → 0.0.29
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
CHANGED
|
@@ -85,37 +85,48 @@ Pour utiliser ce package dans tes autres projets (`bot`, `gateway` ou `mobile`)
|
|
|
85
85
|
|
|
86
86
|
## 📦 Publication
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
La publication passe par **GitHub Actions, sans aucun jeton npm** : le workflow
|
|
89
|
+
[`publish.yml`](.github/workflows/publish.yml) s'authentifie auprès de npm par OIDC
|
|
90
|
+
(« trusted publishing ») et **dépose** la version sans la rendre publique
|
|
91
|
+
(`npm stage publish`). Elle ne devient installable qu'après **approbation avec la 2FA**
|
|
92
|
+
du mainteneur. Un workflow, une action ou une dépendance compromis ne peut donc, au
|
|
93
|
+
pire, que déposer une version qu'on refusera. Le paquet porte en plus une attestation
|
|
94
|
+
de provenance qui le relie au commit et au workflow qui l'ont construit.
|
|
95
|
+
|
|
96
|
+
Jusqu'au 2026-11-03, la publication se faisait depuis le poste avec un jeton « Bypass
|
|
97
|
+
2FA » rangé dans un `.npmrc` : n'importe quel paquet malveillant installé sur la
|
|
98
|
+
machine pouvait le lire et publier à notre place. npm retire d'ailleurs la publication
|
|
99
|
+
directe par jeton en janvier 2027.
|
|
89
100
|
|
|
90
|
-
###
|
|
91
|
-
1. Générer un token sur NPM avec les permissions `Read and Write`.
|
|
92
|
-
2. Restreindre l'accès au package `@syldel/hl-shared-types` uniquement.
|
|
93
|
-
3. Utiliser l'option `Bypass 2FA` pour permettre l'automatisation.
|
|
101
|
+
### Publier une nouvelle version
|
|
94
102
|
|
|
95
|
-
### Commande de publication rapide
|
|
96
|
-
Si tu n'utilises pas de fichier `.npmrc`, tu peux publier en passant le token directement :
|
|
97
103
|
```bash
|
|
98
|
-
npm
|
|
104
|
+
npm version patch # ou minor, major : met à jour package.json et crée le tag v<version>
|
|
105
|
+
git push origin main --follow-tags
|
|
99
106
|
```
|
|
100
107
|
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
Le tag `v*` déclenche le workflow : il vérifie que le tag correspond à `package.json`,
|
|
109
|
+
relance lint, tests, build et le contrôle du contenu du paquet, puis dépose la version.
|
|
110
|
+
Il reste à l'approuver :
|
|
103
111
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
- sur [npmjs.com](https://www.npmjs.com), onglet **Staged Packages**, bouton **Approve** ;
|
|
113
|
+
- ou en ligne de commande : `npm stage list @syldel/hl-shared-types`, puis
|
|
114
|
+
`npm stage approve <stage-id>` (demande la 2FA).
|
|
107
115
|
|
|
108
|
-
|
|
109
|
-
La commande suivante automatise le build, l'incrémentation de version et l'envoi vers NPM :
|
|
116
|
+
Une version déposée par erreur se refuse avec `npm stage reject <stage-id>`.
|
|
110
117
|
|
|
111
|
-
|
|
112
|
-
npm run release
|
|
113
|
-
```
|
|
118
|
+
### Réglages côté npm (une fois)
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
120
|
+
Dans les réglages du paquet sur npmjs.com :
|
|
121
|
+
|
|
122
|
+
- **Trusted Publisher** : GitHub Actions, utilisateur `Syldel`, dépôt `hl-shared-types`, workflow
|
|
123
|
+
`publish.yml`, actions autorisées **`npm stage publish` seulement**. ⚠️ Une
|
|
124
|
+
déclaration neuve expire si aucune publication ne la valide sous **2 jours**.
|
|
125
|
+
- **Publishing access** : « Require two-factor authentication and disallow tokens ».
|
|
126
|
+
|
|
127
|
+
⚠️ Renommer `publish.yml` ou le dépôt casse la publication (ENEEDAUTH) : la déclaration
|
|
128
|
+
sur npmjs.com les nomme exactement. Le champ `repository.url` de `package.json` doit
|
|
129
|
+
aussi correspondre au dépôt GitHub.
|
|
119
130
|
|
|
120
131
|
---
|
|
121
132
|
|
|
@@ -103,9 +103,12 @@ export type CollateralBalance =
|
|
|
103
103
|
* compilation, et non une divergence découverte en réel. Un code qui n'a besoin
|
|
104
104
|
* que du résultat garde `CollateralBalance`, dont celui-ci est un sous-type.
|
|
105
105
|
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
106
|
+
* `asset` est la valeur de `?asset=`, et le gateway refuse en 400 une requête où
|
|
107
|
+
* il manque, est vide ou est répété : toute réponse 200 le porte donc, en chaîne
|
|
108
|
+
* non vide. Ce refus date du 2026-10-19 ; avant lui, une requête sans `?asset=`
|
|
109
|
+
* recevait une réponse sans cette clé (omise par JSON), et ce type était faux
|
|
110
|
+
* pour elle. Éprouvé par les tests du contrôleur, pas contre un gateway qui
|
|
111
|
+
* tourne.
|
|
109
112
|
*/
|
|
110
113
|
export type CollateralBalanceResponse = {
|
|
111
114
|
asset: string;
|
|
@@ -2,17 +2,39 @@
|
|
|
2
2
|
* ============================================================================
|
|
3
3
|
* LE NOM D'UN MARCHÉ DIT DE QUEL CATALOGUE IL RELÈVE
|
|
4
4
|
*
|
|
5
|
-
* Source : doc Hyperliquid « Asset IDs », relevée le 2026-09-30
|
|
5
|
+
* Source : doc Hyperliquid « Asset IDs », relevée le 2026-09-30 et relue le
|
|
6
|
+
* 2026-10-19 (avec les pages « Info endpoint », « Spot » et HIP-4, relues le
|
|
7
|
+
* même jour) :
|
|
6
8
|
*
|
|
7
9
|
* - un perp déployé par un builder porte **toujours** un nom `{dex}:{coin}` —
|
|
8
10
|
* la doc écrit « always », ce n'est pas une heuristique ;
|
|
9
11
|
* - une paire spot se désigne par `10000 + spotInfo.index`, d'où la forme
|
|
10
12
|
* protocolaire `@<index>` ; seules les canoniques portent `BASE/QUOTE`.
|
|
11
13
|
* L'exemple HYPE de la doc (token 150, spot 107) recoupe le relevé du
|
|
12
|
-
* 2026-09-30 : le solde porte `token: 150`, la paire s'appelle `@107
|
|
14
|
+
* 2026-09-30 : le solde porte `token: 150`, la paire s'appelle `@107`. La
|
|
15
|
+
* page « Info endpoint » le dit : pour le spot, `coin` vaut `PURR/USDC` pour
|
|
16
|
+
* PURR et `@{index}` pour toutes les autres paires ;
|
|
17
|
+
* - un **outcome** (HIP-4) porte un coin `#<encodage>` et un jeton
|
|
18
|
+
* `+<encodage>`, avec `encodage = 10 × outcome + côté` (côté 0 ou 1) et un
|
|
19
|
+
* identifiant d'actif `100 000 000 + encodage` — « Outcomes share most
|
|
20
|
+
* implementation details with spot trading », mais leur représentation par
|
|
21
|
+
* l'API diffère du spot comme des perps. Exemple de la doc : outcome 1, côté
|
|
22
|
+
* 0 → `#10`, `+10`, `100000010`. La page HIP-4, elle, ne décrit aucun format
|
|
23
|
+
* de nom : c'est « Asset IDs » qui le fait ;
|
|
13
24
|
* - tout le reste est un perp du dex principal, que l'API désigne par un `dex`
|
|
14
25
|
* vide.
|
|
15
26
|
*
|
|
27
|
+
* ⚠️ « Tout le reste est un perp » était **faux** pour les outcomes jusqu'au
|
|
28
|
+
* 2026-10-19 : `#10` et `+10` rendaient `perp`. Ils existent sur le mainnet
|
|
29
|
+
* (`outcomeMeta` en rend 329 ce jour-là, dont des contests sportifs et des
|
|
30
|
+
* binaires sur prix), alors que la page HIP-4 ne décrit qu'un premier marché
|
|
31
|
+
* quotidien : la doc est en retard sur le réseau. Un outcome est donc un genre
|
|
32
|
+
* à part, que les consommateurs refusent ou traitent — jamais un perp par défaut.
|
|
33
|
+
*
|
|
34
|
+
* Mesuré le 2026-10-19 (`allPerpMetas` : 544 perps ; `spotMeta` : 334 paires,
|
|
35
|
+
* 508 jetons) : aucun nom ne porte de caractère hors `A-Za-z0-9`, `:`, `/`, `@` ;
|
|
36
|
+
* les noms de paires spot sont 1 `PURR/USDC` et 333 `@N`, aucun autre.
|
|
37
|
+
*
|
|
16
38
|
* Ce module vit ici, et non dans le bot ou le mobile, pour la même raison que
|
|
17
39
|
* `tick-and-lot` : qu'il n'en existe **qu'une seule implémentation**. Les deux
|
|
18
40
|
* doivent décider à l'identique de quel univers relève un marché — sans quoi
|
|
@@ -38,7 +60,14 @@ export type HLMarketKind =
|
|
|
38
60
|
/** Perp déployé par un builder (HIP-3) : `vntl:ROBOT`, `xyz:AAPL`. */
|
|
39
61
|
| 'builderPerp'
|
|
40
62
|
/** Paire spot : `PURR/USDC` (canonique) ou `@107` (forme protocolaire). */
|
|
41
|
-
| 'spot'
|
|
63
|
+
| 'spot'
|
|
64
|
+
/**
|
|
65
|
+
* Marché outcome (HIP-4) : coin `#10` ou jeton `+10`, soit `#<encodage>` /
|
|
66
|
+
* `+<encodage>` avec `encodage = 10 × outcome + côté`. Ni un perp, ni une paire
|
|
67
|
+
* spot : son asset id est `100 000 000 + encodage`, et l'API le représente
|
|
68
|
+
* autrement que les deux.
|
|
69
|
+
*/
|
|
70
|
+
| 'outcome';
|
|
42
71
|
/**
|
|
43
72
|
* Le genre de marché que ce nom désigne, ou `null` quand le nom n'en désigne
|
|
44
73
|
* aucun.
|
|
@@ -3,17 +3,39 @@
|
|
|
3
3
|
* ============================================================================
|
|
4
4
|
* LE NOM D'UN MARCHÉ DIT DE QUEL CATALOGUE IL RELÈVE
|
|
5
5
|
*
|
|
6
|
-
* Source : doc Hyperliquid « Asset IDs », relevée le 2026-09-30
|
|
6
|
+
* Source : doc Hyperliquid « Asset IDs », relevée le 2026-09-30 et relue le
|
|
7
|
+
* 2026-10-19 (avec les pages « Info endpoint », « Spot » et HIP-4, relues le
|
|
8
|
+
* même jour) :
|
|
7
9
|
*
|
|
8
10
|
* - un perp déployé par un builder porte **toujours** un nom `{dex}:{coin}` —
|
|
9
11
|
* la doc écrit « always », ce n'est pas une heuristique ;
|
|
10
12
|
* - une paire spot se désigne par `10000 + spotInfo.index`, d'où la forme
|
|
11
13
|
* protocolaire `@<index>` ; seules les canoniques portent `BASE/QUOTE`.
|
|
12
14
|
* L'exemple HYPE de la doc (token 150, spot 107) recoupe le relevé du
|
|
13
|
-
* 2026-09-30 : le solde porte `token: 150`, la paire s'appelle `@107
|
|
15
|
+
* 2026-09-30 : le solde porte `token: 150`, la paire s'appelle `@107`. La
|
|
16
|
+
* page « Info endpoint » le dit : pour le spot, `coin` vaut `PURR/USDC` pour
|
|
17
|
+
* PURR et `@{index}` pour toutes les autres paires ;
|
|
18
|
+
* - un **outcome** (HIP-4) porte un coin `#<encodage>` et un jeton
|
|
19
|
+
* `+<encodage>`, avec `encodage = 10 × outcome + côté` (côté 0 ou 1) et un
|
|
20
|
+
* identifiant d'actif `100 000 000 + encodage` — « Outcomes share most
|
|
21
|
+
* implementation details with spot trading », mais leur représentation par
|
|
22
|
+
* l'API diffère du spot comme des perps. Exemple de la doc : outcome 1, côté
|
|
23
|
+
* 0 → `#10`, `+10`, `100000010`. La page HIP-4, elle, ne décrit aucun format
|
|
24
|
+
* de nom : c'est « Asset IDs » qui le fait ;
|
|
14
25
|
* - tout le reste est un perp du dex principal, que l'API désigne par un `dex`
|
|
15
26
|
* vide.
|
|
16
27
|
*
|
|
28
|
+
* ⚠️ « Tout le reste est un perp » était **faux** pour les outcomes jusqu'au
|
|
29
|
+
* 2026-10-19 : `#10` et `+10` rendaient `perp`. Ils existent sur le mainnet
|
|
30
|
+
* (`outcomeMeta` en rend 329 ce jour-là, dont des contests sportifs et des
|
|
31
|
+
* binaires sur prix), alors que la page HIP-4 ne décrit qu'un premier marché
|
|
32
|
+
* quotidien : la doc est en retard sur le réseau. Un outcome est donc un genre
|
|
33
|
+
* à part, que les consommateurs refusent ou traitent — jamais un perp par défaut.
|
|
34
|
+
*
|
|
35
|
+
* Mesuré le 2026-10-19 (`allPerpMetas` : 544 perps ; `spotMeta` : 334 paires,
|
|
36
|
+
* 508 jetons) : aucun nom ne porte de caractère hors `A-Za-z0-9`, `:`, `/`, `@` ;
|
|
37
|
+
* les noms de paires spot sont 1 `PURR/USDC` et 333 `@N`, aucun autre.
|
|
38
|
+
*
|
|
17
39
|
* Ce module vit ici, et non dans le bot ou le mobile, pour la même raison que
|
|
18
40
|
* `tick-and-lot` : qu'il n'en existe **qu'une seule implémentation**. Les deux
|
|
19
41
|
* doivent décider à l'identique de quel univers relève un marché — sans quoi
|
|
@@ -35,6 +57,10 @@
|
|
|
35
57
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
58
|
exports.hlMarketKind = hlMarketKind;
|
|
37
59
|
exports.hlPerpDexOf = hlPerpDexOf;
|
|
60
|
+
/** `#` (coin) ou `+` (jeton) en tête : la marque d'un outcome, jamais celle d'un perp. */
|
|
61
|
+
const OUTCOME_MARK = /^[#+]/;
|
|
62
|
+
/** La forme documentée : `#<encodage>` ou `+<encodage>`, l'encodage étant un entier. */
|
|
63
|
+
const OUTCOME_NAME = /^[#+]\d+$/;
|
|
38
64
|
/**
|
|
39
65
|
* Le genre de marché que ce nom désigne, ou `null` quand le nom n'en désigne
|
|
40
66
|
* aucun.
|
|
@@ -46,6 +72,14 @@ function hlMarketKind(name) {
|
|
|
46
72
|
// (`cash:XYZ/USDT`), et c'est alors la paire qui prime sur le dex.
|
|
47
73
|
if (name.includes('/') || name.startsWith('@'))
|
|
48
74
|
return 'spot';
|
|
75
|
+
// Un outcome : `#` ou `+`, puis l'encodage — un entier, rien d'autre. Strict à
|
|
76
|
+
// dessein : `#` seul, `#1a` ou `+-3` ne sont pas la forme documentée, et ne sont
|
|
77
|
+
// donc **pas** reconnus comme outcome. Ils ne sont pas non plus des perps : ces
|
|
78
|
+
// deux marques ne désignent jamais un perp, donc un nom qui les porte hors de la
|
|
79
|
+
// forme documentée est un **doute** (`null`), pas « tout le reste ». Doit précéder
|
|
80
|
+
// la règle « tout le reste est un perp ».
|
|
81
|
+
if (OUTCOME_MARK.test(name))
|
|
82
|
+
return OUTCOME_NAME.test(name) ? 'outcome' : null;
|
|
49
83
|
const separator = name.indexOf(':');
|
|
50
84
|
if (separator === -1)
|
|
51
85
|
return 'perp';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syldel/hl-shared-types",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "Shared TypeScript interfaces and types for Hyperliquid integration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix",
|
|
22
22
|
"clean": "rm -rf dist",
|
|
23
23
|
"build": "npm run lint && npm run test && npm run clean && tsc",
|
|
24
|
-
"prepublishOnly": "npm run build"
|
|
25
|
-
"release": "npm run build && npm version patch && npm publish"
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
26
25
|
},
|
|
27
26
|
"publishConfig": {
|
|
28
27
|
"access": "public"
|