@hoox-sh/hoox-shared 1.2.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/README.md +44 -0
- package/dist/agent-config-fields.d.ts +32 -0
- package/dist/agent-config-fields.d.ts.map +1 -0
- package/dist/agent-config-fields.js +220 -0
- package/dist/analytics.d.ts +47 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +45 -0
- package/dist/api-client.d.ts +48 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +191 -0
- package/dist/colors.d.ts +76 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +82 -0
- package/dist/config.d.ts +61 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +146 -0
- package/dist/cron-handler.d.ts +38 -0
- package/dist/cron-handler.d.ts.map +1 -0
- package/dist/cron-handler.js +48 -0
- package/dist/d1/index.d.ts +9 -0
- package/dist/d1/index.d.ts.map +1 -0
- package/dist/d1/index.js +360 -0
- package/dist/d1/repository.d.ts +86 -0
- package/dist/d1/repository.d.ts.map +1 -0
- package/dist/d1/repository.js +297 -0
- package/dist/d1/schemas.d.ts +89 -0
- package/dist/d1/schemas.d.ts.map +1 -0
- package/dist/d1/schemas.js +81 -0
- package/dist/dashboard-manifest.d.ts +135 -0
- package/dist/dashboard-manifest.d.ts.map +1 -0
- package/dist/dashboard-manifest.js +401 -0
- package/dist/errors.d.ts +44 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +149 -0
- package/dist/exchange-client.d.ts +98 -0
- package/dist/exchange-client.d.ts.map +1 -0
- package/dist/exchange-client.js +107 -0
- package/dist/exchanges/base-exchange-client.d.ts +81 -0
- package/dist/exchanges/base-exchange-client.d.ts.map +1 -0
- package/dist/exchanges/base-exchange-client.js +123 -0
- package/dist/exchanges/index.d.ts +7 -0
- package/dist/exchanges/index.d.ts.map +1 -0
- package/dist/exchanges/index.js +123 -0
- package/dist/exchanges/types.d.ts +23 -0
- package/dist/exchanges/types.d.ts.map +1 -0
- package/dist/exchanges/types.js +1 -0
- package/dist/format-time.d.ts +28 -0
- package/dist/format-time.d.ts.map +1 -0
- package/dist/format-time.js +57 -0
- package/dist/formatters.d.ts +36 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +155 -0
- package/dist/health.d.ts +19 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +160 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4198 -0
- package/dist/kvKeys.d.ts +76 -0
- package/dist/kvKeys.d.ts.map +1 -0
- package/dist/kvKeys.js +107 -0
- package/dist/kvUtils.d.ts +30 -0
- package/dist/kvUtils.d.ts.map +1 -0
- package/dist/kvUtils.js +170 -0
- package/dist/legal.d.ts +15 -0
- package/dist/legal.d.ts.map +1 -0
- package/dist/legal.js +40 -0
- package/dist/middleware/auth.d.ts +102 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +151 -0
- package/dist/middleware/cors.d.ts +58 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +77 -0
- package/dist/middleware/index.d.ts +14 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +635 -0
- package/dist/middleware/logger.d.ts +17 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +202 -0
- package/dist/middleware/rate-limit.d.ts +30 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +181 -0
- package/dist/middleware/security-headers.d.ts +43 -0
- package/dist/middleware/security-headers.d.ts.map +1 -0
- package/dist/middleware/security-headers.js +58 -0
- package/dist/middleware/validate.d.ts +25 -0
- package/dist/middleware/validate.d.ts.map +1 -0
- package/dist/middleware/validate.js +56 -0
- package/dist/operator-transport.d.ts +65 -0
- package/dist/operator-transport.d.ts.map +1 -0
- package/dist/operator-transport.js +87 -0
- package/dist/path-utils.d.ts +190 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/path-utils.js +188 -0
- package/dist/queue-handler.d.ts +47 -0
- package/dist/queue-handler.d.ts.map +1 -0
- package/dist/queue-handler.js +46 -0
- package/dist/router.d.ts +15 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +130 -0
- package/dist/schemas/index.d.ts +8 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +705 -0
- package/dist/schemas/registry.d.ts +12 -0
- package/dist/schemas/registry.d.ts.map +1 -0
- package/dist/schemas/registry.js +433 -0
- package/dist/schemas/types.d.ts +83 -0
- package/dist/schemas/types.d.ts.map +1 -0
- package/dist/schemas/types.js +1 -0
- package/dist/schemas/validators.d.ts +39 -0
- package/dist/schemas/validators.d.ts.map +1 -0
- package/dist/schemas/validators.js +290 -0
- package/dist/service-bindings.d.ts +78 -0
- package/dist/service-bindings.d.ts.map +1 -0
- package/dist/service-bindings.js +248 -0
- package/dist/session.d.ts +39 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +261 -0
- package/dist/sse.d.ts +39 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +154 -0
- package/dist/stores/config-store.d.ts +91 -0
- package/dist/stores/config-store.d.ts.map +1 -0
- package/dist/stores/config-store.js +255 -0
- package/dist/stores/service-store.d.ts +266 -0
- package/dist/stores/service-store.d.ts.map +1 -0
- package/dist/stores/service-store.js +516 -0
- package/dist/stores/ui-store.d.ts +67 -0
- package/dist/stores/ui-store.d.ts.map +1 -0
- package/dist/stores/ui-store.js +62 -0
- package/dist/test-utils.d.ts +136 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +128 -0
- package/dist/types/errors.d.ts +20 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +1 -0
- package/dist/types/router.d.ts +36 -0
- package/dist/types/router.d.ts.map +1 -0
- package/dist/types/router.js +1 -0
- package/dist/types.d.ts +442 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +83 -0
- package/dist/wizard/engine.d.ts +46 -0
- package/dist/wizard/engine.d.ts.map +1 -0
- package/dist/wizard/engine.js +525 -0
- package/dist/wizard/index.d.ts +11 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +544 -0
- package/dist/wizard/persistence.d.ts +18 -0
- package/dist/wizard/persistence.d.ts.map +1 -0
- package/dist/wizard/persistence.js +31 -0
- package/dist/wizard/presets.d.ts +38 -0
- package/dist/wizard/presets.d.ts.map +1 -0
- package/dist/wizard/presets.js +223 -0
- package/dist/wizard/provisioner.d.ts +15 -0
- package/dist/wizard/provisioner.d.ts.map +1 -0
- package/dist/wizard/provisioner.js +1 -0
- package/dist/wizard/types.d.ts +76 -0
- package/dist/wizard/types.d.ts.map +1 -0
- package/dist/wizard/types.js +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
+
|
|
18
|
+
// src/exchange-client.ts
|
|
19
|
+
class ExchangeRouter {
|
|
20
|
+
providers = new Map;
|
|
21
|
+
registerProvider(provider) {
|
|
22
|
+
this.providers.set(provider.name.toLowerCase(), provider);
|
|
23
|
+
}
|
|
24
|
+
route(exchange, env, options) {
|
|
25
|
+
const key = exchange.toLowerCase();
|
|
26
|
+
const provider = this.providers.get(key);
|
|
27
|
+
if (!provider) {
|
|
28
|
+
throw new Error(`Unsupported exchange: ${exchange}`);
|
|
29
|
+
}
|
|
30
|
+
if (options?.testnet && provider.supportsTestTrading === false) {
|
|
31
|
+
throw new Error(`TEST_TRADING_UNSUPPORTED: ${exchange} does not support test/sandbox trading via API`);
|
|
32
|
+
}
|
|
33
|
+
if (!provider.hasCredentials(env)) {
|
|
34
|
+
throw new Error(`API secret bindings not configured or accessible for ${exchange}`);
|
|
35
|
+
}
|
|
36
|
+
return { exchange: key, client: provider.createClient(env, options) };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class BaseExchangeClient {
|
|
41
|
+
apiKey;
|
|
42
|
+
apiSecret;
|
|
43
|
+
baseUrl;
|
|
44
|
+
isTestnet;
|
|
45
|
+
constructor(config) {
|
|
46
|
+
if (!config.apiKey || !config.apiSecret) {
|
|
47
|
+
throw new Error("API key and secret are required.");
|
|
48
|
+
}
|
|
49
|
+
this.apiKey = config.apiKey;
|
|
50
|
+
this.apiSecret = config.apiSecret;
|
|
51
|
+
this.baseUrl = config.baseUrl || this.getDefaultBaseUrl();
|
|
52
|
+
this.isTestnet = config.testnet || false;
|
|
53
|
+
}
|
|
54
|
+
async fetch(method, path, params) {
|
|
55
|
+
const url = `${this.baseUrl}${path}`;
|
|
56
|
+
const headers = this.buildHeaders(method, path, params);
|
|
57
|
+
const body = params ? new URLSearchParams(params).toString() : undefined;
|
|
58
|
+
const response = await fetch(url, {
|
|
59
|
+
method,
|
|
60
|
+
headers,
|
|
61
|
+
body: method !== "GET" ? body : undefined
|
|
62
|
+
});
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
const error = await response.text();
|
|
65
|
+
throw new Error(`Exchange API error: ${response.status} - ${error}`);
|
|
66
|
+
}
|
|
67
|
+
return response.json();
|
|
68
|
+
}
|
|
69
|
+
async openLong(symbol, quantity, price, orderType = "MARKET") {
|
|
70
|
+
return this.executeTrade({
|
|
71
|
+
symbol,
|
|
72
|
+
side: "long",
|
|
73
|
+
orderType,
|
|
74
|
+
quantity,
|
|
75
|
+
price
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async openShort(symbol, quantity, price, orderType = "MARKET") {
|
|
79
|
+
return this.executeTrade({
|
|
80
|
+
symbol,
|
|
81
|
+
side: "short",
|
|
82
|
+
orderType,
|
|
83
|
+
quantity,
|
|
84
|
+
price
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async closeLong(symbol, quantity) {
|
|
88
|
+
return this.executeTrade({
|
|
89
|
+
symbol,
|
|
90
|
+
side: "long",
|
|
91
|
+
quantity,
|
|
92
|
+
reduceOnly: true
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async closeShort(symbol, quantity) {
|
|
96
|
+
return this.executeTrade({
|
|
97
|
+
symbol,
|
|
98
|
+
side: "short",
|
|
99
|
+
quantity,
|
|
100
|
+
reduceOnly: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
ExchangeRouter,
|
|
106
|
+
BaseExchangeClient
|
|
107
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
export interface ExchangeConfig {
|
|
6
|
+
apiKey: string;
|
|
7
|
+
apiSecret: string;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
testnet?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Optional constructor options for exchange clients. */
|
|
12
|
+
export interface ExchangeClientOptions {
|
|
13
|
+
/** Override the default API base URL. */
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
/** When true, use the exchange testnet/sandbox endpoint (if supported). */
|
|
16
|
+
testnet?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface TradeParams {
|
|
19
|
+
symbol: string;
|
|
20
|
+
side: string;
|
|
21
|
+
orderType?: string;
|
|
22
|
+
quantity: number;
|
|
23
|
+
price?: number;
|
|
24
|
+
reduceOnly?: boolean;
|
|
25
|
+
leverage?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface OrderResponse {
|
|
28
|
+
orderId: string;
|
|
29
|
+
symbol: string;
|
|
30
|
+
status: string;
|
|
31
|
+
executedQty?: string;
|
|
32
|
+
price?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface Position {
|
|
35
|
+
symbol: string;
|
|
36
|
+
side: "long" | "short";
|
|
37
|
+
quantity: number;
|
|
38
|
+
entryPrice: number;
|
|
39
|
+
unrealizedPnl?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Base class for exchange clients. All exchange implementations must extend this.
|
|
43
|
+
* Provides common functionality for exchange API clients including signature generation,
|
|
44
|
+
* HTTP requests, and trade execution helpers.
|
|
45
|
+
*/
|
|
46
|
+
export declare abstract class BaseExchangeClient {
|
|
47
|
+
protected readonly apiKey: string;
|
|
48
|
+
protected readonly apiSecret: string;
|
|
49
|
+
protected readonly baseUrl: string;
|
|
50
|
+
protected readonly isTestnet: boolean;
|
|
51
|
+
protected readonly importedKeyPromise: Promise<CryptoKey>;
|
|
52
|
+
constructor(apiKey: string, apiSecret: string, options?: ExchangeClientOptions);
|
|
53
|
+
/** Whether this client instance is targeting a testnet/sandbox host. */
|
|
54
|
+
get testnet(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Returns the error message prefix for this client.
|
|
57
|
+
* Subclasses can override to customize error messages.
|
|
58
|
+
*/
|
|
59
|
+
protected getErrorMessagePrefix(): string;
|
|
60
|
+
protected abstract getDefaultBaseUrl(): string;
|
|
61
|
+
protected generateSignature(_params: Record<string, string | number | boolean>): Promise<string>;
|
|
62
|
+
protected buildHeaders(_method: string, _path: string, _params?: Record<string, string | number | boolean>): Headers;
|
|
63
|
+
/**
|
|
64
|
+
* Imports the API secret as a CryptoKey for HMAC-SHA256 signing.
|
|
65
|
+
*/
|
|
66
|
+
private importKey;
|
|
67
|
+
/**
|
|
68
|
+
* Signs data using HMAC-SHA256 with the API secret.
|
|
69
|
+
*/
|
|
70
|
+
protected cryptoSign(data: string): Promise<string>;
|
|
71
|
+
protected fetch<T>(method: string, path: string, params?: Record<string, string | number | boolean>): Promise<T>;
|
|
72
|
+
setLeverage(_symbol: string, _leverage: number): Promise<void>;
|
|
73
|
+
executeTrade(_params: TradeParams): Promise<OrderResponse>;
|
|
74
|
+
getAccountInfo(): Promise<Record<string, unknown>>;
|
|
75
|
+
getPositions(_symbol?: string): Promise<Position[]>;
|
|
76
|
+
openLong(symbol: string, quantity: number, price?: number, orderType?: string): Promise<OrderResponse>;
|
|
77
|
+
openShort(symbol: string, quantity: number, price?: number, orderType?: string): Promise<OrderResponse>;
|
|
78
|
+
closeLong(symbol: string, quantity: number): Promise<OrderResponse>;
|
|
79
|
+
closeShort(symbol: string, quantity: number): Promise<OrderResponse>;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=base-exchange-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-exchange-client.d.ts","sourceRoot":"","sources":["../../src/exchanges/base-exchange-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
+
|
|
18
|
+
// src/exchanges/base-exchange-client.ts
|
|
19
|
+
class BaseExchangeClient {
|
|
20
|
+
apiKey;
|
|
21
|
+
apiSecret;
|
|
22
|
+
baseUrl;
|
|
23
|
+
isTestnet;
|
|
24
|
+
importedKeyPromise;
|
|
25
|
+
constructor(apiKey, apiSecret, options) {
|
|
26
|
+
if (!apiKey || !apiSecret) {
|
|
27
|
+
throw new Error(this.getErrorMessagePrefix() + "API key and secret are required.");
|
|
28
|
+
}
|
|
29
|
+
this.apiKey = apiKey;
|
|
30
|
+
this.apiSecret = apiSecret;
|
|
31
|
+
this.isTestnet = options?.testnet ?? false;
|
|
32
|
+
this.baseUrl = options?.baseUrl ?? this.getDefaultBaseUrl();
|
|
33
|
+
this.importedKeyPromise = this.importKey();
|
|
34
|
+
}
|
|
35
|
+
get testnet() {
|
|
36
|
+
return this.isTestnet;
|
|
37
|
+
}
|
|
38
|
+
getErrorMessagePrefix() {
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
generateSignature(_params) {
|
|
42
|
+
throw new Error("generateSignature must be implemented by subclass");
|
|
43
|
+
}
|
|
44
|
+
buildHeaders(_method, _path, _params) {
|
|
45
|
+
return new Headers;
|
|
46
|
+
}
|
|
47
|
+
async importKey() {
|
|
48
|
+
const encoder = new TextEncoder;
|
|
49
|
+
return crypto.subtle.importKey("raw", encoder.encode(this.apiSecret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
50
|
+
}
|
|
51
|
+
async cryptoSign(data) {
|
|
52
|
+
const encoder = new TextEncoder;
|
|
53
|
+
const key = await this.importedKeyPromise;
|
|
54
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(data));
|
|
55
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
56
|
+
}
|
|
57
|
+
async fetch(method, path, params) {
|
|
58
|
+
const url = `${this.baseUrl}${path}`;
|
|
59
|
+
const headers = this.buildHeaders(method, path, params);
|
|
60
|
+
const body = params ? new URLSearchParams(params).toString() : undefined;
|
|
61
|
+
const response = await fetch(url, {
|
|
62
|
+
method,
|
|
63
|
+
headers,
|
|
64
|
+
body: method !== "GET" ? body : undefined
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const error = await response.text();
|
|
68
|
+
throw new Error(`Exchange API error: ${response.status} - ${error}`);
|
|
69
|
+
}
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
setLeverage(_symbol, _leverage) {
|
|
73
|
+
throw new Error("setLeverage must be implemented by subclass");
|
|
74
|
+
}
|
|
75
|
+
executeTrade(_params) {
|
|
76
|
+
throw new Error("executeTrade must be implemented by subclass");
|
|
77
|
+
}
|
|
78
|
+
getAccountInfo() {
|
|
79
|
+
throw new Error("getAccountInfo must be implemented by subclass");
|
|
80
|
+
}
|
|
81
|
+
getPositions(_symbol) {
|
|
82
|
+
throw new Error("getPositions must be implemented by subclass");
|
|
83
|
+
}
|
|
84
|
+
async openLong(symbol, quantity, price, orderType = "MARKET") {
|
|
85
|
+
return this.executeTrade({
|
|
86
|
+
symbol,
|
|
87
|
+
side: "BUY",
|
|
88
|
+
orderType,
|
|
89
|
+
quantity,
|
|
90
|
+
price
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async openShort(symbol, quantity, price, orderType = "MARKET") {
|
|
94
|
+
return this.executeTrade({
|
|
95
|
+
symbol,
|
|
96
|
+
side: "SELL",
|
|
97
|
+
orderType,
|
|
98
|
+
quantity,
|
|
99
|
+
price
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async closeLong(symbol, quantity) {
|
|
103
|
+
return this.executeTrade({
|
|
104
|
+
symbol,
|
|
105
|
+
side: "SELL",
|
|
106
|
+
orderType: "MARKET",
|
|
107
|
+
quantity,
|
|
108
|
+
reduceOnly: true
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async closeShort(symbol, quantity) {
|
|
112
|
+
return this.executeTrade({
|
|
113
|
+
symbol,
|
|
114
|
+
side: "BUY",
|
|
115
|
+
orderType: "MARKET",
|
|
116
|
+
quantity,
|
|
117
|
+
reduceOnly: true
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export {
|
|
122
|
+
BaseExchangeClient
|
|
123
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
export { BaseExchangeClient, type ExchangeConfig, type ExchangeClientOptions, type TradeParams, type OrderResponse, type Position, } from "./base-exchange-client";
|
|
6
|
+
export type { SupportedExchange } from "./types";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exchanges/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,QAAQ,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
+
|
|
18
|
+
// src/exchanges/base-exchange-client.ts
|
|
19
|
+
class BaseExchangeClient {
|
|
20
|
+
apiKey;
|
|
21
|
+
apiSecret;
|
|
22
|
+
baseUrl;
|
|
23
|
+
isTestnet;
|
|
24
|
+
importedKeyPromise;
|
|
25
|
+
constructor(apiKey, apiSecret, options) {
|
|
26
|
+
if (!apiKey || !apiSecret) {
|
|
27
|
+
throw new Error(this.getErrorMessagePrefix() + "API key and secret are required.");
|
|
28
|
+
}
|
|
29
|
+
this.apiKey = apiKey;
|
|
30
|
+
this.apiSecret = apiSecret;
|
|
31
|
+
this.isTestnet = options?.testnet ?? false;
|
|
32
|
+
this.baseUrl = options?.baseUrl ?? this.getDefaultBaseUrl();
|
|
33
|
+
this.importedKeyPromise = this.importKey();
|
|
34
|
+
}
|
|
35
|
+
get testnet() {
|
|
36
|
+
return this.isTestnet;
|
|
37
|
+
}
|
|
38
|
+
getErrorMessagePrefix() {
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
generateSignature(_params) {
|
|
42
|
+
throw new Error("generateSignature must be implemented by subclass");
|
|
43
|
+
}
|
|
44
|
+
buildHeaders(_method, _path, _params) {
|
|
45
|
+
return new Headers;
|
|
46
|
+
}
|
|
47
|
+
async importKey() {
|
|
48
|
+
const encoder = new TextEncoder;
|
|
49
|
+
return crypto.subtle.importKey("raw", encoder.encode(this.apiSecret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
50
|
+
}
|
|
51
|
+
async cryptoSign(data) {
|
|
52
|
+
const encoder = new TextEncoder;
|
|
53
|
+
const key = await this.importedKeyPromise;
|
|
54
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(data));
|
|
55
|
+
return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
56
|
+
}
|
|
57
|
+
async fetch(method, path, params) {
|
|
58
|
+
const url = `${this.baseUrl}${path}`;
|
|
59
|
+
const headers = this.buildHeaders(method, path, params);
|
|
60
|
+
const body = params ? new URLSearchParams(params).toString() : undefined;
|
|
61
|
+
const response = await fetch(url, {
|
|
62
|
+
method,
|
|
63
|
+
headers,
|
|
64
|
+
body: method !== "GET" ? body : undefined
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const error = await response.text();
|
|
68
|
+
throw new Error(`Exchange API error: ${response.status} - ${error}`);
|
|
69
|
+
}
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
setLeverage(_symbol, _leverage) {
|
|
73
|
+
throw new Error("setLeverage must be implemented by subclass");
|
|
74
|
+
}
|
|
75
|
+
executeTrade(_params) {
|
|
76
|
+
throw new Error("executeTrade must be implemented by subclass");
|
|
77
|
+
}
|
|
78
|
+
getAccountInfo() {
|
|
79
|
+
throw new Error("getAccountInfo must be implemented by subclass");
|
|
80
|
+
}
|
|
81
|
+
getPositions(_symbol) {
|
|
82
|
+
throw new Error("getPositions must be implemented by subclass");
|
|
83
|
+
}
|
|
84
|
+
async openLong(symbol, quantity, price, orderType = "MARKET") {
|
|
85
|
+
return this.executeTrade({
|
|
86
|
+
symbol,
|
|
87
|
+
side: "BUY",
|
|
88
|
+
orderType,
|
|
89
|
+
quantity,
|
|
90
|
+
price
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async openShort(symbol, quantity, price, orderType = "MARKET") {
|
|
94
|
+
return this.executeTrade({
|
|
95
|
+
symbol,
|
|
96
|
+
side: "SELL",
|
|
97
|
+
orderType,
|
|
98
|
+
quantity,
|
|
99
|
+
price
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async closeLong(symbol, quantity) {
|
|
103
|
+
return this.executeTrade({
|
|
104
|
+
symbol,
|
|
105
|
+
side: "SELL",
|
|
106
|
+
orderType: "MARKET",
|
|
107
|
+
quantity,
|
|
108
|
+
reduceOnly: true
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async closeShort(symbol, quantity) {
|
|
112
|
+
return this.executeTrade({
|
|
113
|
+
symbol,
|
|
114
|
+
side: "BUY",
|
|
115
|
+
orderType: "MARKET",
|
|
116
|
+
quantity,
|
|
117
|
+
reduceOnly: true
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export {
|
|
122
|
+
BaseExchangeClient
|
|
123
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
export type SupportedExchange = "binance" | "bybit" | "mexc";
|
|
6
|
+
export interface ExchangeOrder {
|
|
7
|
+
orderId: string;
|
|
8
|
+
symbol: string;
|
|
9
|
+
side: "BUY" | "SELL";
|
|
10
|
+
quantity: number;
|
|
11
|
+
price?: number;
|
|
12
|
+
leverage?: number;
|
|
13
|
+
status: "PENDING" | "FILLED" | "CANCELED" | "FAILED";
|
|
14
|
+
}
|
|
15
|
+
export interface ExchangePosition {
|
|
16
|
+
symbol: string;
|
|
17
|
+
quantity: number;
|
|
18
|
+
leverage: number;
|
|
19
|
+
markPrice: number;
|
|
20
|
+
unrealizedPnl: number;
|
|
21
|
+
side: "LONG" | "SHORT";
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exchanges/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;CACtD;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// @bun
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Relative time formatter — converts a timestamp (ms) into a human-readable
|
|
7
|
+
* "time ago" string. Used by the StatusBar stale-data indicator and toast
|
|
8
|
+
* notifications for reconnection downtime.
|
|
9
|
+
*
|
|
10
|
+
* Format: "< 1m ago", "2m ago", "1h ago", "3d ago", "> 30d ago"
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Format a timestamp as a relative "X ago" string.
|
|
14
|
+
*
|
|
15
|
+
* @param timestampMs Unix timestamp in milliseconds
|
|
16
|
+
* @param nowMs Optional "now" reference (defaults to Date.now())
|
|
17
|
+
* @returns Relative time string (e.g. "5m ago")
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatRelativeTime(timestampMs: number, nowMs?: number): string;
|
|
20
|
+
/**
|
|
21
|
+
* Format a duration in milliseconds as a compact human-readable string.
|
|
22
|
+
* Used for reconnection downtime toasts.
|
|
23
|
+
*
|
|
24
|
+
* @param durationMs Duration in milliseconds
|
|
25
|
+
* @returns Compact duration string (e.g. "12s", "2m 30s")
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatDuration(durationMs: number): string;
|
|
28
|
+
//# sourceMappingURL=format-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-time.d.ts","sourceRoot":"","sources":["../src/format-time.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AAEH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAkBR;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAczD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __returnValue = (v) => v;
|
|
4
|
+
function __exportSetter(name, newValue) {
|
|
5
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
6
|
+
}
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
set: __exportSetter.bind(all, name)
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
17
|
+
|
|
18
|
+
// src/format-time.ts
|
|
19
|
+
function formatRelativeTime(timestampMs, nowMs) {
|
|
20
|
+
const now = nowMs ?? Date.now();
|
|
21
|
+
const diffMs = now - timestampMs;
|
|
22
|
+
if (diffMs < 0)
|
|
23
|
+
return "just now";
|
|
24
|
+
if (timestampMs === 0)
|
|
25
|
+
return "\u2014";
|
|
26
|
+
const seconds = Math.floor(diffMs / 1000);
|
|
27
|
+
const minutes = Math.floor(seconds / 60);
|
|
28
|
+
const hours = Math.floor(minutes / 60);
|
|
29
|
+
const days = Math.floor(hours / 24);
|
|
30
|
+
if (seconds < 60)
|
|
31
|
+
return "< 1m ago";
|
|
32
|
+
if (minutes < 60)
|
|
33
|
+
return `${minutes}m ago`;
|
|
34
|
+
if (hours < 24)
|
|
35
|
+
return `${hours}h ago`;
|
|
36
|
+
if (days < 30)
|
|
37
|
+
return `${days}d ago`;
|
|
38
|
+
return `> 30d ago`;
|
|
39
|
+
}
|
|
40
|
+
function formatDuration(durationMs) {
|
|
41
|
+
const seconds = Math.floor(durationMs / 1000);
|
|
42
|
+
const minutes = Math.floor(seconds / 60);
|
|
43
|
+
const hours = Math.floor(minutes / 60);
|
|
44
|
+
if (hours > 0) {
|
|
45
|
+
const remainMin = minutes % 60;
|
|
46
|
+
return remainMin > 0 ? `${hours}h ${remainMin}m` : `${hours}h`;
|
|
47
|
+
}
|
|
48
|
+
if (minutes > 0) {
|
|
49
|
+
const remainSec = seconds % 60;
|
|
50
|
+
return remainSec > 0 ? `${minutes}m ${remainSec}s` : `${minutes}m`;
|
|
51
|
+
}
|
|
52
|
+
return `${seconds}s`;
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
formatRelativeTime,
|
|
56
|
+
formatDuration
|
|
57
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 HOOX · HOOX · jango-blockchained (hoox-sh)
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Formatters — Number, currency, duration, and timestamp formatting utilities.
|
|
7
|
+
*
|
|
8
|
+
* Pure functions — no side effects, safe for NaN/Infinity/negative/zero.
|
|
9
|
+
*/
|
|
10
|
+
/** Format large numbers with K/M/B suffixes */
|
|
11
|
+
export declare function formatNumber(n: number): string;
|
|
12
|
+
/** Format as compact currency */
|
|
13
|
+
export declare function formatCurrency(n: number): string;
|
|
14
|
+
/** Compact currency without sign prefix for raw values */
|
|
15
|
+
export declare function formatCompactCurrency(n: number): string;
|
|
16
|
+
/** Format duration in seconds to human-readable */
|
|
17
|
+
export declare function formatDuration(seconds: number): string;
|
|
18
|
+
/** Compact duration (e.g. "72h", "1d 3h") */
|
|
19
|
+
export declare function formatDurationCompact(seconds: number): string;
|
|
20
|
+
/** ISO timestamp to human-readable */
|
|
21
|
+
export declare function formatTimestamp(iso: string): string;
|
|
22
|
+
/** Relative time (e.g. "2m ago", "1h ago", "3d ago") */
|
|
23
|
+
export declare function formatRelativeTime(timestamp: number): string;
|
|
24
|
+
/** Format percentage */
|
|
25
|
+
export declare function formatPercent(n: number, decimals?: number): string;
|
|
26
|
+
/** Uptime seconds to human-readable */
|
|
27
|
+
export declare function formatUptime(seconds: number): string;
|
|
28
|
+
/** Latency in ms */
|
|
29
|
+
export declare function formatLatency(ms: number): string;
|
|
30
|
+
/** Request count */
|
|
31
|
+
export declare function formatRequests(n: number): string;
|
|
32
|
+
/** Memory in MB */
|
|
33
|
+
export declare function formatMemory(usedMB: number, limitMB: number): string;
|
|
34
|
+
/** CPU time in ms */
|
|
35
|
+
export declare function formatCpu(ms: number): string;
|
|
36
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM9C;AAED,iCAAiC;AACjC,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED,0DAA0D;AAC1D,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAYtD;AAED,6CAA6C;AAC7C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAS7D;AAED,sCAAsC;AACtC,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAY5D;AAED,wBAAwB;AACxB,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAI7D;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,oBAAoB;AACpB,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,oBAAoB;AACpB,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,mBAAmB;AACnB,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIpE;AAED,qBAAqB;AACrB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG5C"}
|