@pear-protocol/exchanges-sdk 0.0.1

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.
Files changed (48) hide show
  1. package/README.md +187 -0
  2. package/dist/account/account-manager.d.ts +34 -0
  3. package/dist/account/account-manager.js +140 -0
  4. package/dist/account/exchange-account.d.ts +36 -0
  5. package/dist/account/exchange-account.js +185 -0
  6. package/dist/account/exchanges/base.d.ts +49 -0
  7. package/dist/account/exchanges/base.js +63 -0
  8. package/dist/account/exchanges/binance/const.d.ts +10 -0
  9. package/dist/account/exchanges/binance/const.js +10 -0
  10. package/dist/account/exchanges/binance/mapper.d.ts +9 -0
  11. package/dist/account/exchanges/binance/mapper.js +96 -0
  12. package/dist/account/exchanges/binance/orchestrator.d.ts +35 -0
  13. package/dist/account/exchanges/binance/orchestrator.js +232 -0
  14. package/dist/account/exchanges/binance/rest.d.ts +13 -0
  15. package/dist/account/exchanges/binance/rest.js +81 -0
  16. package/dist/account/exchanges/binance/types.d.ts +77 -0
  17. package/dist/account/exchanges/binance/types.js +1 -0
  18. package/dist/account/exchanges/binance/ws.d.ts +21 -0
  19. package/dist/account/exchanges/binance/ws.js +85 -0
  20. package/dist/account/exchanges/bybit/const.d.ts +7 -0
  21. package/dist/account/exchanges/bybit/const.js +7 -0
  22. package/dist/account/exchanges/bybit/mapper.d.ts +11 -0
  23. package/dist/account/exchanges/bybit/mapper.js +106 -0
  24. package/dist/account/exchanges/bybit/orchestrator.d.ts +23 -0
  25. package/dist/account/exchanges/bybit/orchestrator.js +159 -0
  26. package/dist/account/exchanges/bybit/rest.d.ts +11 -0
  27. package/dist/account/exchanges/bybit/rest.js +110 -0
  28. package/dist/account/exchanges/bybit/types.d.ts +59 -0
  29. package/dist/account/exchanges/bybit/types.js +1 -0
  30. package/dist/account/exchanges/bybit/ws.d.ts +18 -0
  31. package/dist/account/exchanges/bybit/ws.js +74 -0
  32. package/dist/account/exchanges/index.d.ts +8 -0
  33. package/dist/account/exchanges/index.js +16 -0
  34. package/dist/account/index.d.ts +8 -0
  35. package/dist/account/index.js +4 -0
  36. package/dist/account/types.d.ts +81 -0
  37. package/dist/account/types.js +1 -0
  38. package/dist/account/utils.d.ts +7 -0
  39. package/dist/account/utils.js +15 -0
  40. package/dist/credentials.d.ts +28 -0
  41. package/dist/credentials.js +46 -0
  42. package/dist/index.d.ts +22 -0
  43. package/dist/index.js +21 -0
  44. package/dist/utils/hmac.d.ts +4 -0
  45. package/dist/utils/hmac.js +17 -0
  46. package/dist/utils/ws.d.ts +7 -0
  47. package/dist/utils/ws.js +25 -0
  48. package/package.json +36 -0
@@ -0,0 +1,81 @@
1
+ import { Connector, BinanceUSDMCredentialsDTO, BybitCredentialsDTO } from '@pear-protocol/types';
2
+
3
+ type MarginMode = 'cross' | 'isolated';
4
+ interface AssetBalance {
5
+ asset: string;
6
+ free: string;
7
+ used: string;
8
+ total: string;
9
+ walletBalance: string;
10
+ unrealizedPnl: string;
11
+ usdValue: string;
12
+ initialMargin: string;
13
+ maintenanceMargin: string;
14
+ isCollateral: boolean;
15
+ collateralRatio: string;
16
+ borrowedAmount: string;
17
+ }
18
+ interface AccountBalance {
19
+ exchange: string;
20
+ accountType: string;
21
+ marginMode: string;
22
+ free: Record<string, string>;
23
+ used: Record<string, string>;
24
+ total: Record<string, string>;
25
+ availableToTrade: string;
26
+ totalEquity: string;
27
+ walletBalance: string;
28
+ unrealizedPnl: string;
29
+ initialMarginUsed: string;
30
+ maintenanceMargin: string;
31
+ marginRatio: string;
32
+ assets: AssetBalance[];
33
+ timestamp: number;
34
+ }
35
+ interface AccountPosition {
36
+ symbol: string;
37
+ side: 'long' | 'short' | 'both';
38
+ size: string;
39
+ entryPrice: string;
40
+ unrealizedPnl: string;
41
+ leverage: string;
42
+ marginType: MarginMode;
43
+ liquidationPrice: string | null;
44
+ }
45
+ interface TrackedAssetInfo {
46
+ coin: string;
47
+ leverage: string;
48
+ marginType: MarginMode;
49
+ availableToTrade: [string, string] | null;
50
+ maxTradeSzs: [string, string] | null;
51
+ collateralToken: string | null;
52
+ }
53
+ interface ExchangeState {
54
+ balance: AccountBalance | null;
55
+ positions: Map<string, AccountPosition>;
56
+ leverageSettings: Map<string, string>;
57
+ trackedAssets: Map<string, TrackedAssetInfo>;
58
+ lastUpdated: number;
59
+ initialized: boolean;
60
+ }
61
+ type BalanceCallback = (balance: AccountBalance) => void;
62
+ type PositionsCallback = (positions: AccountPosition[]) => void;
63
+ type TrackedAssetCallback = (info: TrackedAssetInfo) => void;
64
+ interface Tracker<T> {
65
+ get(): T;
66
+ untrack(): void;
67
+ }
68
+ interface AccountConfig {
69
+ exchange: Connector;
70
+ demo?: boolean;
71
+ onAuthError?: () => void;
72
+ }
73
+ type SupportedCredentials = BinanceUSDMCredentialsDTO | BybitCredentialsDTO;
74
+ interface StateUpdate {
75
+ balance?: AccountBalance;
76
+ positions?: Map<string, AccountPosition>;
77
+ leverageSettings?: Map<string, string>;
78
+ trackedAssets?: Map<string, TrackedAssetInfo>;
79
+ }
80
+
81
+ export type { AccountBalance, AccountConfig, AccountPosition, AssetBalance, BalanceCallback, ExchangeState, MarginMode, PositionsCallback, StateUpdate, SupportedCredentials, TrackedAssetCallback, TrackedAssetInfo, Tracker };
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,7 @@
1
+ import { ExchangeState } from './types.js';
2
+ import '@pear-protocol/types';
3
+
4
+ declare function createEmptyState(): ExchangeState;
5
+ declare function positionKey(symbol: string, side: string): string;
6
+
7
+ export { createEmptyState, positionKey };
@@ -0,0 +1,15 @@
1
+ function createEmptyState() {
2
+ return {
3
+ balance: null,
4
+ positions: /* @__PURE__ */ new Map(),
5
+ leverageSettings: /* @__PURE__ */ new Map(),
6
+ trackedAssets: /* @__PURE__ */ new Map(),
7
+ lastUpdated: 0,
8
+ initialized: false
9
+ };
10
+ }
11
+ function positionKey(symbol, side) {
12
+ return `${symbol}:${side}`;
13
+ }
14
+
15
+ export { createEmptyState, positionKey };
@@ -0,0 +1,28 @@
1
+ import PearSDK from '@pear-protocol/core-sdk';
2
+ import { Connector, ConnectorCredentialsDTO } from '@pear-protocol/types';
3
+
4
+ declare class Credentials {
5
+ private sdk;
6
+ private cache;
7
+ constructor(sdk: PearSDK);
8
+ /**
9
+ * Fetch exchange credentials from the backend and cache them in memory.
10
+ */
11
+ fetch<T extends Connector>(tradeAccountId: string): Promise<ConnectorCredentialsDTO[T]>;
12
+ /**
13
+ * Get previously fetched credentials from the in-memory cache.
14
+ * Returns null if not yet fetched in this SDK instance.
15
+ */
16
+ get<T extends Connector>(tradeAccountId: string): ConnectorCredentialsDTO[T] | null;
17
+ /**
18
+ * Get credentials from in-memory cache or fetch from the backend if not available.
19
+ */
20
+ getOrFetch<T extends Connector>(tradeAccountId: string): Promise<ConnectorCredentialsDTO[T]>;
21
+ /**
22
+ * Clear in-memory credentials for a specific trade account,
23
+ * or all cached credentials if no ID is provided.
24
+ */
25
+ clear(tradeAccountId?: string): void;
26
+ }
27
+
28
+ export { Credentials };
@@ -0,0 +1,46 @@
1
+ class Credentials {
2
+ sdk;
3
+ cache = /* @__PURE__ */ new Map();
4
+ constructor(sdk) {
5
+ this.sdk = sdk;
6
+ }
7
+ /**
8
+ * Fetch exchange credentials from the backend and cache them in memory.
9
+ */
10
+ async fetch(tradeAccountId) {
11
+ const response = await this.sdk.info.accounts.credentials(tradeAccountId);
12
+ const credentials = response.credentials;
13
+ this.cache.set(tradeAccountId, { credentials, connector: response.connector });
14
+ return credentials;
15
+ }
16
+ /**
17
+ * Get previously fetched credentials from the in-memory cache.
18
+ * Returns null if not yet fetched in this SDK instance.
19
+ */
20
+ get(tradeAccountId) {
21
+ const cached = this.cache.get(tradeAccountId);
22
+ if (!cached) return null;
23
+ return cached.credentials;
24
+ }
25
+ /**
26
+ * Get credentials from in-memory cache or fetch from the backend if not available.
27
+ */
28
+ async getOrFetch(tradeAccountId) {
29
+ const cached = this.get(tradeAccountId);
30
+ if (cached) return cached;
31
+ return await this.fetch(tradeAccountId);
32
+ }
33
+ /**
34
+ * Clear in-memory credentials for a specific trade account,
35
+ * or all cached credentials if no ID is provided.
36
+ */
37
+ clear(tradeAccountId) {
38
+ if (tradeAccountId) {
39
+ this.cache.delete(tradeAccountId);
40
+ } else {
41
+ this.cache.clear();
42
+ }
43
+ }
44
+ }
45
+
46
+ export { Credentials };
@@ -0,0 +1,22 @@
1
+ import PearSDK from '@pear-protocol/core-sdk';
2
+ import { AccountManager } from './account/account-manager.js';
3
+ export { ExchangeAccount } from './account/exchange-account.js';
4
+ export { createOrchestrator } from './account/exchanges/index.js';
5
+ export { AccountBalance, AccountConfig, AccountPosition, AssetBalance, BalanceCallback, ExchangeState, MarginMode, PositionsCallback, StateUpdate, SupportedCredentials, TrackedAssetCallback, TrackedAssetInfo, Tracker } from './account/types.js';
6
+ import { Credentials } from './credentials.js';
7
+ export { Orchestrator, OrchestratorConfig } from './account/exchanges/base.js';
8
+ import '@pear-protocol/types';
9
+
10
+ type ExchangesSDKConfig = {
11
+ sdk: PearSDK;
12
+ demo?: boolean;
13
+ };
14
+ declare class ExchangesSDK {
15
+ credentials: Credentials;
16
+ account: AccountManager;
17
+ sdk: PearSDK;
18
+ constructor(config: ExchangesSDKConfig);
19
+ destroy(): void;
20
+ }
21
+
22
+ export { AccountManager, Credentials, ExchangesSDK, type ExchangesSDKConfig };
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ import { AccountManager } from './account';
2
+ export * from './account';
3
+ import { Credentials } from './credentials';
4
+ export * from './credentials';
5
+
6
+ class ExchangesSDK {
7
+ credentials;
8
+ account;
9
+ sdk;
10
+ constructor(config) {
11
+ this.sdk = config.sdk;
12
+ this.credentials = new Credentials(config.sdk);
13
+ this.account = new AccountManager(this.credentials, config.demo);
14
+ }
15
+ destroy() {
16
+ this.account.destroy();
17
+ this.credentials.clear();
18
+ }
19
+ }
20
+
21
+ export { ExchangesSDK };
@@ -0,0 +1,4 @@
1
+ declare function hmacSha256Hex(secret: string, message: string): Promise<string>;
2
+ declare function hmacSha256Base64(secret: string, message: string): Promise<string>;
3
+
4
+ export { hmacSha256Base64, hmacSha256Hex };
@@ -0,0 +1,17 @@
1
+ const encoder = new TextEncoder();
2
+ async function hmacSha256Hex(secret, message) {
3
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, [
4
+ "sign"
5
+ ]);
6
+ const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
7
+ return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
8
+ }
9
+ async function hmacSha256Base64(secret, message) {
10
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, [
11
+ "sign"
12
+ ]);
13
+ const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
14
+ return btoa(String.fromCharCode(...new Uint8Array(signature)));
15
+ }
16
+
17
+ export { hmacSha256Base64, hmacSha256Hex };
@@ -0,0 +1,7 @@
1
+ declare function reconnectDelay(attempt: number): number;
2
+ declare function connectWs(url: string): Promise<WebSocket>;
3
+ declare function sendWs(ws: WebSocket | null, msg: Record<string, unknown> | string): void;
4
+ declare function clearTimer(timer: ReturnType<typeof setTimeout> | null): null;
5
+ declare function clearIntervalTimer(timer: ReturnType<typeof setInterval> | null): null;
6
+
7
+ export { clearIntervalTimer, clearTimer, connectWs, reconnectDelay, sendWs };
@@ -0,0 +1,25 @@
1
+ function reconnectDelay(attempt) {
2
+ return Math.min(1e3 * 2 ** (attempt - 1), 3e4);
3
+ }
4
+ function connectWs(url) {
5
+ return new Promise((resolve, reject) => {
6
+ const ws = new WebSocket(url);
7
+ ws.onopen = () => resolve(ws);
8
+ ws.onerror = () => reject(new Error(`WebSocket connection failed: ${url}`));
9
+ });
10
+ }
11
+ function sendWs(ws, msg) {
12
+ if (ws?.readyState === WebSocket.OPEN) {
13
+ ws.send(typeof msg === "string" ? msg : JSON.stringify(msg));
14
+ }
15
+ }
16
+ function clearTimer(timer) {
17
+ if (timer) clearTimeout(timer);
18
+ return null;
19
+ }
20
+ function clearIntervalTimer(timer) {
21
+ if (timer) clearInterval(timer);
22
+ return null;
23
+ }
24
+
25
+ export { clearIntervalTimer, clearTimer, connectWs, reconnectDelay, sendWs };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@pear-protocol/exchanges-sdk",
3
+ "version": "0.0.1",
4
+ "description": "Pear Protocol Exchanges SDK",
5
+ "private": false,
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "sideEffects": false,
22
+ "scripts": {
23
+ "build": "tsup",
24
+ "clean": "rm -rf dist .turbo",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "dependencies": {
28
+ "@pear-protocol/core-sdk": "0.0.3",
29
+ "@pear-protocol/types": "0.0.3"
30
+ },
31
+ "devDependencies": {
32
+ "@backend/typescript-config": "workspace:*",
33
+ "tsup": "8.5.1",
34
+ "typescript": "5.9.3"
35
+ }
36
+ }