@blackcube/xgate-sdk 0.20.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/LICENSE +28 -0
- package/README.md +142 -0
- package/dist/index.cjs +1165 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1048 -0
- package/dist/index.d.ts +1048 -0
- package/dist/index.js +1147 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Blackcube
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# @blackcube/xgate-sdk
|
|
2
|
+
|
|
3
|
+
La passerelle NestJS qui unifie les dix SDK d'exchange Blackcube derrière **une seule surface** :
|
|
4
|
+
un catalogue, des bougies, des prix, un portefeuille et du trading — quelle que soit la venue.
|
|
5
|
+
|
|
6
|
+
> **SDK communautaire / non officiel.** Non affilié aux exchanges couverts. Usage à vos risques.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm add @blackcube/xgate-sdk
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Node.js ≥ 22. Les SDK de venue sont des dépendances : on n'en installe aucun séparément.
|
|
15
|
+
|
|
16
|
+
## Ce que XGate gère, venue par venue
|
|
17
|
+
|
|
18
|
+
Trois niveaux, et ils ne se valent pas. **Le tableau dit ce qui est PROUVÉ, pas ce qui est écrit** :
|
|
19
|
+
une capacité n'est comptée que si un test réel l'a exercée.
|
|
20
|
+
|
|
21
|
+
| Venue | Catalogue · bougies · prix | Portefeuille | Trading | Ouverture protégée |
|
|
22
|
+
|---|:---:|:---:|:---:|:---:|
|
|
23
|
+
| **hyperliquid** | ✔ | ✔ | ✔ | ✔ **prouvée** |
|
|
24
|
+
| **pacifica** | ✔ | ✔ | ✔ | ✔ **prouvée** |
|
|
25
|
+
| **aster** | ✔ | ✔ | ✔ | ⚠ **à valider** |
|
|
26
|
+
| lighter | ✔ | — | — | — |
|
|
27
|
+
| extended | ✔ | — | — | — |
|
|
28
|
+
| paradex | ✔ | — | — | — |
|
|
29
|
+
| bullet | ✔ | — | — | — |
|
|
30
|
+
| blofin | ✔ | ✔ | ✔ | — |
|
|
31
|
+
| binance | ✔ *(+ comptant)* | — | — | — |
|
|
32
|
+
| bybit | ✔ *(+ comptant)* | — | — | — |
|
|
33
|
+
|
|
34
|
+
**hyperliquid et pacifica sont complètes et prouvées.** Le cycle entier — ouvrir avec stop, lire la
|
|
35
|
+
position, refermer sans reliquat — tourne sur leur testnet à chaque exécution de la suite de tests.
|
|
36
|
+
|
|
37
|
+
**aster est complète mais non validée**, et le refus est délibéré. Son `/fapi/v3/batchOrders` coupe
|
|
38
|
+
à ~3,26 s en répondant « The request has timed out. » *alors que la venue a déjà créé une partie des
|
|
39
|
+
ordres* : deux exécutions identiques ont produit deux sous-ensembles différents. Un statut inconnu
|
|
40
|
+
sur une ouverture protégée, c'est la position nue que ce paquet existe pour rendre impossible — donc
|
|
41
|
+
`openWithProtection` y **lève** tant que la preuve manque. Tout le reste (positions, ordres,
|
|
42
|
+
historique, clôture) fonctionne. Détail complet dans le backlog.
|
|
43
|
+
|
|
44
|
+
**Les autres sont en lecture.** Elles servent le catalogue, les bougies et les prix ; il leur manque
|
|
45
|
+
un accès de compte (clé d'API pour bullet, adresse active pour lighter, extended et paradex) ou la
|
|
46
|
+
partie signée n'est pas câblée. Binance et bybit sont volontairement limitées au **public** : leurs
|
|
47
|
+
SDK ne couvrent que catalogue, bougies et prix, et toute route signée y lève.
|
|
48
|
+
|
|
49
|
+
## Les services
|
|
50
|
+
|
|
51
|
+
Chacun est un `@Injectable()` NestJS, utilisable seul ou via `XgateModule`.
|
|
52
|
+
|
|
53
|
+
| Service | Ce qu'il rend |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `CatalogService` | les paires perpétuelles de toutes les venues, normalisées |
|
|
56
|
+
| `SpotCatalogService` | les paires **comptant** — binance et bybit uniquement |
|
|
57
|
+
| `CandlesService` | les bougies REST, avec agrégation quand la venue ne sert pas l'intervalle |
|
|
58
|
+
| `WsCandlesService` | les bougies en temps réel, un handler pour N venues |
|
|
59
|
+
| `PricesService` | mark, oracle, mid, bid/ask, funding, open interest |
|
|
60
|
+
| `WalletService` | soldes, mouvements, historique d'équité |
|
|
61
|
+
| `TradingService` | positions, ordres, exécutions, ouverture protégée, clôture |
|
|
62
|
+
|
|
63
|
+
## Le trading
|
|
64
|
+
|
|
65
|
+
**Jamais un ordre sans stop.** `openWithProtection` est la seule façon d'ouvrir une position, et
|
|
66
|
+
elle exige un `slPct`. La protection part **avec** l'entrée, en un geste que la venue traite
|
|
67
|
+
atomiquement : si l'entrée ne remplit pas, la protection ne naît jamais.
|
|
68
|
+
|
|
69
|
+
**L'appelant donne des pourcentages, jamais des prix.** XGate calcule les niveaux depuis le prix
|
|
70
|
+
d'entrée, les arrondit à la grille de la paire, et garantit qu'au-delà de 80 % de parts cumulées la
|
|
71
|
+
position ferme entièrement — sans reliquat de 0,01 qui traîne.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { TradingService, XgateEx } from '@blackcube/xgate-sdk';
|
|
75
|
+
|
|
76
|
+
const trading = new TradingService();
|
|
77
|
+
const access = {
|
|
78
|
+
xex: XgateEx.Hyperliquid,
|
|
79
|
+
address: '0x…',
|
|
80
|
+
privateKey: '0x…',
|
|
81
|
+
network: 'testnet' as const,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const orders = await trading.openWithProtection(access, {
|
|
85
|
+
xex: XgateEx.Hyperliquid,
|
|
86
|
+
symbolXex: 'ETH',
|
|
87
|
+
direction: 'long',
|
|
88
|
+
size: 0.02,
|
|
89
|
+
entry: 3120,
|
|
90
|
+
slPct: 0.02, // stop à 2 % sous l'entrée
|
|
91
|
+
tps: [{ pct: 0.03, part: 0.5 }, // 50 % à +3 %
|
|
92
|
+
{ pct: 0.06, part: 0.5 }], // 50 % à +6 % → somme 100 %, clôture intégrale
|
|
93
|
+
tif: 'ioc',
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Le premier ordre rendu est l'entrée ; les suivants sont le stop et les take-profits.
|
|
98
|
+
|
|
99
|
+
### Fermer
|
|
100
|
+
|
|
101
|
+
`closePosition` relit la position **sur la venue** avant de la fermer, et sort la taille que la venue
|
|
102
|
+
déclare — jamais celle qu'on avait prévue. Fermer la taille planifiée laisse un reliquat dès que le
|
|
103
|
+
fill a différé du plan, et ce reliquat reste ouvert, sans stop.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
await trading.closePosition(access, 'ETH'); // null s'il n'y avait rien à fermer
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Le réseau est explicite
|
|
110
|
+
|
|
111
|
+
`network` vaut `mainnet` par défaut. **Le préciser est la seule chose qui sépare un test d'un ordre
|
|
112
|
+
réel** : sur les venues à testnet, `network: 'testnet'` fait tout basculer, signature comprise.
|
|
113
|
+
|
|
114
|
+
Le vocabulaire est le même partout — `mainnet` / `testnet` — y compris chez blofin, qui appelle le
|
|
115
|
+
second « demo trading ». Une clé de démo envoyée au mainnet fait répondre « Access key does not
|
|
116
|
+
exist » : le message accuse la clé alors que c'est l'adresse qui est fausse.
|
|
117
|
+
|
|
118
|
+
## Les statuts d'ordre
|
|
119
|
+
|
|
120
|
+
Sept valeurs, **identiques à celles des SDK de venue**, orthographe comprise :
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
open · partiallyFilled · filled · canceled · rejected · expired · other
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`canceled` prend **un seul L**. Un statut inconnu retombe sur `other` plutôt que de traverser la
|
|
127
|
+
passerelle tel quel : `ORDER_STATUSES` est exporté pour valider plutôt que caster.
|
|
128
|
+
|
|
129
|
+
## Les conventions qui traversent tout
|
|
130
|
+
|
|
131
|
+
- **Une bougie inclut sa dernière milliseconde** : 10:00:00.000 → 10:59:59.999. `closedAt` se
|
|
132
|
+
**calcule**, il ne se recopie jamais du wire.
|
|
133
|
+
- **Aucun `time: number`** : chaque date dit ce qu'elle date — `openedAt`, `closedAt`, `quotedAt`,
|
|
134
|
+
`occurredAt`, `measuredAt`, `placedAt`, `filledAt`.
|
|
135
|
+
- **Les montants sont des chaînes.** Un `number` sur un prix de BTC perd des décimales là où ça
|
|
136
|
+
compte.
|
|
137
|
+
- **Une taille de position est toujours positive** : le sens est porté par `side`.
|
|
138
|
+
- **Pas de mensuel.** Les intervalles s'arrêtent à `1w`.
|
|
139
|
+
|
|
140
|
+
## Documentation
|
|
141
|
+
|
|
142
|
+
Le détail par service vit dans les docblocks — ils portent le *pourquoi*, pas la paraphrase du code.
|