@pear-protocol/exchanges-sdk 0.6.7 → 0.8.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 +105 -25
- package/dist/client/bybit/rest.js +8 -1
- package/dist/client/hyperliquid/rest.js +21 -1
- package/dist/client/lighter/rest.js +6 -12
- package/dist/client/okx/rest.js +5 -1
- package/dist/index.d.ts +1131 -78
- package/dist/sdk.js +9 -2
- package/dist/syncer/base.js +36 -14
- package/dist/tracker/balance-core.js +89 -0
- package/dist/tracker/balance.js +25 -0
- package/dist/tracker/basket-size.js +194 -0
- package/dist/tracker/binance/balance.js +11 -0
- package/dist/tracker/binance/mapper.js +87 -42
- package/dist/tracker/binance/tracker.js +29 -14
- package/dist/tracker/binance/types.js +0 -6
- package/dist/tracker/bybit/balance.js +14 -0
- package/dist/tracker/bybit/mapper.js +109 -52
- package/dist/tracker/bybit/tracker.js +242 -33
- package/dist/tracker/bybit/types.js +0 -7
- package/dist/tracker/hyperliquid/account-mode.js +14 -0
- package/dist/tracker/hyperliquid/balance.js +184 -0
- package/dist/tracker/hyperliquid/basket-size.js +93 -0
- package/dist/tracker/hyperliquid/coin-name.js +18 -0
- package/dist/tracker/hyperliquid/collateral.js +48 -0
- package/dist/tracker/hyperliquid/decimal.js +28 -0
- package/dist/tracker/hyperliquid/mapper.js +399 -176
- package/dist/tracker/hyperliquid/spot-pricing.js +106 -0
- package/dist/tracker/hyperliquid/tracker.js +237 -78
- package/dist/tracker/hyperliquid/types.js +1 -7
- package/dist/tracker/index.js +9 -7
- package/dist/tracker/lighter/balance.js +87 -0
- package/dist/tracker/lighter/basket-size.js +74 -0
- package/dist/tracker/lighter/mapper.js +324 -145
- package/dist/tracker/lighter/tracker.js +228 -117
- package/dist/tracker/lighter/types.js +1 -7
- package/dist/tracker/okx/balance.js +17 -0
- package/dist/tracker/okx/mapper.js +156 -58
- package/dist/tracker/okx/tracker.js +228 -29
- package/dist/tracker/okx/types.js +0 -8
- package/dist/tracker/types.js +0 -24
- package/package.json +7 -9
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import PearSDK from '@pear-protocol/core-sdk';
|
|
|
3
3
|
import { ProxyConfig } from '@pear-protocol/utils';
|
|
4
4
|
import { WebSocket } from 'partysocket';
|
|
5
5
|
import { WalletClient, Transport, Chain, Account } from 'viem';
|
|
6
|
+
import { z } from 'zod';
|
|
6
7
|
|
|
7
8
|
type SupportedCredentials = HttpTypes.ExchangeCredentialsResponse['credentials'];
|
|
8
9
|
type ExchangesSDKConfig = {
|
|
@@ -561,9 +562,26 @@ interface AccountSyncerConfig {
|
|
|
561
562
|
credentials: SupportedCredentials;
|
|
562
563
|
demo: boolean;
|
|
563
564
|
}
|
|
565
|
+
/**
|
|
566
|
+
* Outcome of one fill sync cycle, so batch/cron callers can tell a completed
|
|
567
|
+
* cycle apart from one that must be retried:
|
|
568
|
+
* - `synced`: the cycle posted, or there was nothing to post.
|
|
569
|
+
* - `deferred`: the server answered 409 SYNC_CREATE_*; the watermark did not
|
|
570
|
+
* advance, so a later cycle retries the same window.
|
|
571
|
+
* - `aborted`: the exchange fetch failed; nothing was posted.
|
|
572
|
+
*/
|
|
573
|
+
type FillSyncOutcome = 'synced' | 'deferred' | 'aborted';
|
|
574
|
+
/**
|
|
575
|
+
* Outcome of one funding sync cycle. Funding has no server deferral contract,
|
|
576
|
+
* so the union is narrower than {@link FillSyncOutcome}:
|
|
577
|
+
* - `synced`: the cycle posted, or there were no new payments.
|
|
578
|
+
* - `aborted`: the exchange funding fetch failed; nothing was posted.
|
|
579
|
+
* A failed post still throws — only the exchange fetch is guarded.
|
|
580
|
+
*/
|
|
581
|
+
type FundingSyncOutcome = 'synced' | 'aborted';
|
|
564
582
|
interface AccountSyncer {
|
|
565
|
-
synchronizeFills(): Promise<
|
|
566
|
-
synchronizeFunding(): Promise<
|
|
583
|
+
synchronizeFills(): Promise<FillSyncOutcome>;
|
|
584
|
+
synchronizeFunding(): Promise<FundingSyncOutcome>;
|
|
567
585
|
}
|
|
568
586
|
interface ListExternalFillsParams {
|
|
569
587
|
since: Date;
|
|
@@ -613,8 +631,8 @@ declare abstract class BaseAccountSyncer<ExternalFill> implements AccountSyncer
|
|
|
613
631
|
* Independent of the fill sync cycle (`synchronizeFills`) — funding rows are
|
|
614
632
|
* immutable and upsert idempotently, so this is driven on its own cadence.
|
|
615
633
|
*/
|
|
616
|
-
synchronizeFunding(): Promise<
|
|
617
|
-
synchronizeFills(): Promise<
|
|
634
|
+
synchronizeFunding(): Promise<FundingSyncOutcome>;
|
|
635
|
+
synchronizeFills(): Promise<FillSyncOutcome>;
|
|
618
636
|
}
|
|
619
637
|
|
|
620
638
|
interface BinanceRawUserTrade {
|
|
@@ -809,65 +827,440 @@ declare class OkxAccountSyncer extends BaseAccountSyncer<RawFill> {
|
|
|
809
827
|
private contractsToBase;
|
|
810
828
|
}
|
|
811
829
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
REGULAR_MARGIN = "REGULAR_MARGIN",
|
|
820
|
-
PORTFOLIO_MARGIN = "PORTFOLIO_MARGIN"
|
|
821
|
-
}
|
|
830
|
+
/**
|
|
831
|
+
* The account balance a consumer receives, as one discriminated union over `accountMode`.
|
|
832
|
+
*
|
|
833
|
+
* Narrowing on the tag gives exactly the fields that venue and mode support and no others, and a
|
|
834
|
+
* newly added mode fails every exhaustive `switch` at compile time. This module sits above the
|
|
835
|
+
* venue variant files, which in turn sit above `./balance-core` — one direction, no cycle.
|
|
836
|
+
*/
|
|
822
837
|
|
|
823
|
-
declare
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
838
|
+
declare const AccountBalance: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
839
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
840
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
841
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
842
|
+
poolsShared: z.ZodBoolean;
|
|
843
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
844
|
+
asset: z.ZodString;
|
|
845
|
+
equity: z.ZodString;
|
|
846
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
847
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
848
|
+
}, z.core.$strip>>;
|
|
849
|
+
timestamp: z.ZodNumber;
|
|
850
|
+
accountMode: z.ZodLiteral<"hyperliquid:standard">;
|
|
851
|
+
spotEquity: z.ZodNullable<z.ZodString>;
|
|
852
|
+
perpsEquity: z.ZodString;
|
|
853
|
+
vaultEquity: z.ZodString;
|
|
854
|
+
stakedEquity: z.ZodNullable<z.ZodString>;
|
|
855
|
+
unrealizedPnl: z.ZodString;
|
|
856
|
+
maintenanceMargin: z.ZodString;
|
|
857
|
+
crossMarginRatio: z.ZodString;
|
|
858
|
+
crossAccountLeverage: z.ZodString;
|
|
859
|
+
perDexState: z.ZodArray<z.ZodObject<{
|
|
860
|
+
dex: z.ZodString;
|
|
861
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
862
|
+
accountValue: z.ZodString;
|
|
863
|
+
crossNotional: z.ZodString;
|
|
864
|
+
crossMaintenanceMargin: z.ZodString;
|
|
865
|
+
withdrawable: z.ZodString;
|
|
866
|
+
}, z.core.$strip>>;
|
|
867
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
868
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
869
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
870
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
871
|
+
poolsShared: z.ZodBoolean;
|
|
872
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
873
|
+
asset: z.ZodString;
|
|
874
|
+
equity: z.ZodString;
|
|
875
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
876
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
877
|
+
}, z.core.$strip>>;
|
|
878
|
+
timestamp: z.ZodNumber;
|
|
879
|
+
accountMode: z.ZodLiteral<"hyperliquid:unified">;
|
|
880
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
881
|
+
vaultEquity: z.ZodString;
|
|
882
|
+
stakedEquity: z.ZodNullable<z.ZodString>;
|
|
883
|
+
portfolioValue: z.ZodNullable<z.ZodString>;
|
|
884
|
+
unrealizedPnl: z.ZodString;
|
|
885
|
+
perpsMaintenanceMargin: z.ZodString;
|
|
886
|
+
unifiedAccountRatio: z.ZodString;
|
|
887
|
+
unifiedAccountLeverage: z.ZodNullable<z.ZodString>;
|
|
888
|
+
perDexState: z.ZodArray<z.ZodObject<{
|
|
889
|
+
dex: z.ZodString;
|
|
890
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
891
|
+
accountValue: z.ZodString;
|
|
892
|
+
crossNotional: z.ZodString;
|
|
893
|
+
crossMaintenanceMargin: z.ZodString;
|
|
894
|
+
withdrawable: z.ZodString;
|
|
895
|
+
}, z.core.$strip>>;
|
|
896
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
897
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
898
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
899
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
900
|
+
poolsShared: z.ZodBoolean;
|
|
901
|
+
timestamp: z.ZodNumber;
|
|
902
|
+
accountMode: z.ZodLiteral<"hyperliquid:portfolioMargin">;
|
|
903
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
904
|
+
asset: z.ZodString;
|
|
905
|
+
equity: z.ZodString;
|
|
906
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
907
|
+
withdrawable: z.ZodString;
|
|
908
|
+
ltv: z.ZodNullable<z.ZodString>;
|
|
909
|
+
borrowCapUsed: z.ZodNullable<z.ZodString>;
|
|
910
|
+
}, z.core.$strip>>;
|
|
911
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
912
|
+
vaultEquity: z.ZodString;
|
|
913
|
+
stakedEquity: z.ZodNullable<z.ZodString>;
|
|
914
|
+
portfolioValue: z.ZodNullable<z.ZodString>;
|
|
915
|
+
unrealizedPnl: z.ZodString;
|
|
916
|
+
perpsMaintenanceMargin: z.ZodString;
|
|
917
|
+
portfolioMarginRatio: z.ZodNullable<z.ZodString>;
|
|
918
|
+
portfolioAccountLeverage: z.ZodNullable<z.ZodString>;
|
|
919
|
+
borrowCapUsed: z.ZodNullable<z.ZodString>;
|
|
920
|
+
perDexState: z.ZodArray<z.ZodObject<{
|
|
921
|
+
dex: z.ZodString;
|
|
922
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
923
|
+
accountValue: z.ZodString;
|
|
924
|
+
crossNotional: z.ZodString;
|
|
925
|
+
crossMaintenanceMargin: z.ZodString;
|
|
926
|
+
withdrawable: z.ZodString;
|
|
927
|
+
}, z.core.$strip>>;
|
|
928
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
929
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
930
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
931
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
932
|
+
poolsShared: z.ZodBoolean;
|
|
933
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
934
|
+
asset: z.ZodString;
|
|
935
|
+
equity: z.ZodString;
|
|
936
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
937
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
938
|
+
}, z.core.$strip>>;
|
|
939
|
+
timestamp: z.ZodNumber;
|
|
940
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
941
|
+
perpetualsEquity: z.ZodNullable<z.ZodString>;
|
|
942
|
+
spotEquity: z.ZodNullable<z.ZodString>;
|
|
943
|
+
publicPoolsEquity: z.ZodNullable<z.ZodString>;
|
|
944
|
+
stakingEquity: z.ZodNullable<z.ZodString>;
|
|
945
|
+
creditedInLit: z.ZodNullable<z.ZodString>;
|
|
946
|
+
unrealizedPnl: z.ZodNullable<z.ZodString>;
|
|
947
|
+
crossLeverage: z.ZodNullable<z.ZodString>;
|
|
948
|
+
maintenanceMargin: z.ZodNullable<z.ZodString>;
|
|
949
|
+
crossMarginUsage: z.ZodNullable<z.ZodString>;
|
|
950
|
+
crossMarginRatio: z.ZodNullable<z.ZodString>;
|
|
951
|
+
accountMode: z.ZodLiteral<"lighter:classic">;
|
|
952
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
953
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
954
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
955
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
956
|
+
poolsShared: z.ZodBoolean;
|
|
957
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
958
|
+
asset: z.ZodString;
|
|
959
|
+
equity: z.ZodString;
|
|
960
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
961
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
962
|
+
}, z.core.$strip>>;
|
|
963
|
+
timestamp: z.ZodNumber;
|
|
964
|
+
portfolioMargin: z.ZodNullable<z.ZodString>;
|
|
965
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
966
|
+
perpetualsEquity: z.ZodNullable<z.ZodString>;
|
|
967
|
+
spotEquity: z.ZodNullable<z.ZodString>;
|
|
968
|
+
publicPoolsEquity: z.ZodNullable<z.ZodString>;
|
|
969
|
+
stakingEquity: z.ZodNullable<z.ZodString>;
|
|
970
|
+
creditedInLit: z.ZodNullable<z.ZodString>;
|
|
971
|
+
unrealizedPnl: z.ZodNullable<z.ZodString>;
|
|
972
|
+
crossLeverage: z.ZodNullable<z.ZodString>;
|
|
973
|
+
maintenanceMargin: z.ZodNullable<z.ZodString>;
|
|
974
|
+
crossMarginUsage: z.ZodNullable<z.ZodString>;
|
|
975
|
+
crossMarginRatio: z.ZodNullable<z.ZodString>;
|
|
976
|
+
accountMode: z.ZodLiteral<"lighter:unified">;
|
|
977
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
978
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
979
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
980
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
981
|
+
poolsShared: z.ZodBoolean;
|
|
982
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
983
|
+
asset: z.ZodString;
|
|
984
|
+
equity: z.ZodString;
|
|
985
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
986
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
987
|
+
}, z.core.$strip>>;
|
|
988
|
+
timestamp: z.ZodNumber;
|
|
989
|
+
accountMode: z.ZodLiteral<"binance:singleAsset">;
|
|
990
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
991
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
992
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
993
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
994
|
+
poolsShared: z.ZodBoolean;
|
|
995
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
996
|
+
asset: z.ZodString;
|
|
997
|
+
equity: z.ZodString;
|
|
998
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
999
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1000
|
+
}, z.core.$strip>>;
|
|
1001
|
+
timestamp: z.ZodNumber;
|
|
1002
|
+
accountMode: z.ZodLiteral<"binance:multiAsset">;
|
|
1003
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1004
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1005
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1006
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1007
|
+
poolsShared: z.ZodBoolean;
|
|
1008
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1009
|
+
asset: z.ZodString;
|
|
1010
|
+
equity: z.ZodString;
|
|
1011
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1012
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1013
|
+
}, z.core.$strip>>;
|
|
1014
|
+
timestamp: z.ZodNumber;
|
|
1015
|
+
accountMode: z.ZodLiteral<"bybit:isolatedMargin">;
|
|
1016
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1017
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1018
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1019
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1020
|
+
poolsShared: z.ZodBoolean;
|
|
1021
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1022
|
+
asset: z.ZodString;
|
|
1023
|
+
equity: z.ZodString;
|
|
1024
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1025
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1026
|
+
}, z.core.$strip>>;
|
|
1027
|
+
timestamp: z.ZodNumber;
|
|
1028
|
+
accountMode: z.ZodLiteral<"bybit:regularMargin">;
|
|
1029
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1030
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1031
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1032
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1033
|
+
poolsShared: z.ZodBoolean;
|
|
1034
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1035
|
+
asset: z.ZodString;
|
|
1036
|
+
equity: z.ZodString;
|
|
1037
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1038
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1039
|
+
}, z.core.$strip>>;
|
|
1040
|
+
timestamp: z.ZodNumber;
|
|
1041
|
+
accountMode: z.ZodLiteral<"bybit:portfolioMargin">;
|
|
1042
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1043
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1044
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1045
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1046
|
+
poolsShared: z.ZodBoolean;
|
|
1047
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1048
|
+
asset: z.ZodString;
|
|
1049
|
+
equity: z.ZodString;
|
|
1050
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1051
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1052
|
+
}, z.core.$strip>>;
|
|
1053
|
+
timestamp: z.ZodNumber;
|
|
1054
|
+
accountMode: z.ZodLiteral<"okx:spot">;
|
|
1055
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1056
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1057
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1058
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1059
|
+
poolsShared: z.ZodBoolean;
|
|
1060
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1061
|
+
asset: z.ZodString;
|
|
1062
|
+
equity: z.ZodString;
|
|
1063
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1064
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1065
|
+
}, z.core.$strip>>;
|
|
1066
|
+
timestamp: z.ZodNumber;
|
|
1067
|
+
accountMode: z.ZodLiteral<"okx:futures">;
|
|
1068
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1069
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1070
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1071
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1072
|
+
poolsShared: z.ZodBoolean;
|
|
1073
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1074
|
+
asset: z.ZodString;
|
|
1075
|
+
equity: z.ZodString;
|
|
1076
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1077
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1078
|
+
}, z.core.$strip>>;
|
|
1079
|
+
timestamp: z.ZodNumber;
|
|
1080
|
+
accountMode: z.ZodLiteral<"okx:multiCurrencyMargin">;
|
|
1081
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1082
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1083
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1084
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1085
|
+
poolsShared: z.ZodBoolean;
|
|
1086
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1087
|
+
asset: z.ZodString;
|
|
1088
|
+
equity: z.ZodString;
|
|
1089
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1090
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1091
|
+
}, z.core.$strip>>;
|
|
1092
|
+
timestamp: z.ZodNumber;
|
|
1093
|
+
accountMode: z.ZodLiteral<"okx:portfolioMargin">;
|
|
1094
|
+
}, z.core.$strip>], "accountMode">;
|
|
1095
|
+
type AccountBalance = z.infer<typeof AccountBalance>;
|
|
829
1096
|
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1097
|
+
/**
|
|
1098
|
+
* The primitives every account-balance variant is built from: decimal string formats, the
|
|
1099
|
+
* `accountMode` union tag, and the four core fields every venue fills in every mode.
|
|
1100
|
+
*
|
|
1101
|
+
* This module is the root of the balance schema graph — venue variant files import it, and the
|
|
1102
|
+
* union in `./balance` imports those. Keeping the primitives out of `./balance` is what stops
|
|
1103
|
+
* that graph from becoming a cycle.
|
|
1104
|
+
*/
|
|
836
1105
|
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1106
|
+
/** Unsigned decimal, e.g. "1234.56". Never a JS number — precision is load-bearing. */
|
|
1107
|
+
declare const DecimalString: z.ZodString;
|
|
1108
|
+
/** Signed decimal, e.g. "+1234.56" / "-1234.56". BUY positive, SELL negative. */
|
|
1109
|
+
declare const SignedDecimalString: z.ZodString;
|
|
1110
|
+
declare const MarginMode: z.ZodEnum<{
|
|
1111
|
+
isolated: "isolated";
|
|
1112
|
+
cross: "cross";
|
|
1113
|
+
}>;
|
|
1114
|
+
type MarginMode = z.infer<typeof MarginMode>;
|
|
1115
|
+
declare const Side: z.ZodEnum<{
|
|
1116
|
+
BUY: "BUY";
|
|
1117
|
+
SELL: "SELL";
|
|
1118
|
+
}>;
|
|
1119
|
+
type Side = z.infer<typeof Side>;
|
|
1120
|
+
/**
|
|
1121
|
+
* The union tag: venue AND mode in one literal, so narrowing needs no separate venue check.
|
|
1122
|
+
* `hyperliquid:standard` covers the API's `default` and `disabled` — verified identical.
|
|
1123
|
+
*/
|
|
1124
|
+
declare const AccountMode: z.ZodEnum<{
|
|
1125
|
+
"hyperliquid:standard": "hyperliquid:standard";
|
|
1126
|
+
"hyperliquid:unified": "hyperliquid:unified";
|
|
1127
|
+
"hyperliquid:portfolioMargin": "hyperliquid:portfolioMargin";
|
|
1128
|
+
"lighter:classic": "lighter:classic";
|
|
1129
|
+
"lighter:unified": "lighter:unified";
|
|
1130
|
+
"binance:singleAsset": "binance:singleAsset";
|
|
1131
|
+
"binance:multiAsset": "binance:multiAsset";
|
|
1132
|
+
"bybit:isolatedMargin": "bybit:isolatedMargin";
|
|
1133
|
+
"bybit:regularMargin": "bybit:regularMargin";
|
|
1134
|
+
"bybit:portfolioMargin": "bybit:portfolioMargin";
|
|
1135
|
+
"okx:spot": "okx:spot";
|
|
1136
|
+
"okx:futures": "okx:futures";
|
|
1137
|
+
"okx:multiCurrencyMargin": "okx:multiCurrencyMargin";
|
|
1138
|
+
"okx:portfolioMargin": "okx:portfolioMargin";
|
|
1139
|
+
}>;
|
|
1140
|
+
type AccountMode = z.infer<typeof AccountMode>;
|
|
1141
|
+
/** One collateral pool's own figures, in THAT asset's own units. Never converted. */
|
|
1142
|
+
declare const CollateralBalance: z.ZodObject<{
|
|
1143
|
+
asset: z.ZodString;
|
|
1144
|
+
equity: z.ZodString;
|
|
1145
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1146
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1147
|
+
}, z.core.$strip>;
|
|
1148
|
+
type CollateralBalance = z.infer<typeof CollateralBalance>;
|
|
1149
|
+
/**
|
|
1150
|
+
* Filled by every venue in every mode: the USD scalars a consumer reads without narrowing, plus the
|
|
1151
|
+
* per-collateral rows that say what is actually spendable in each currency.
|
|
1152
|
+
*
|
|
1153
|
+
* The rows are per-asset by construction, so the only USD figures in a variant are the scalars —
|
|
1154
|
+
* which is what makes mixing units impossible rather than merely discouraged.
|
|
1155
|
+
*/
|
|
1156
|
+
declare const AccountBalanceCore: z.ZodObject<{
|
|
1157
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1158
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1159
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1160
|
+
poolsShared: z.ZodBoolean;
|
|
1161
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1162
|
+
asset: z.ZodString;
|
|
1163
|
+
equity: z.ZodString;
|
|
1164
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1165
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1166
|
+
}, z.core.$strip>>;
|
|
1167
|
+
timestamp: z.ZodNumber;
|
|
1168
|
+
}, z.core.$strip>;
|
|
1169
|
+
/** Human-readable name for each mode, as the venue's own account page labels it. */
|
|
1170
|
+
declare const ACCOUNT_MODE_LABELS: Record<AccountMode, string>;
|
|
843
1171
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1172
|
+
/**
|
|
1173
|
+
* Mirrors the shipped basket model (`BasketItem` in the frontend): unsigned `weight`
|
|
1174
|
+
* with `side` alongside, weights summing to 100. Sizing ignores `side` — margin
|
|
1175
|
+
* requirement does not depend on direction — and normalises by Σweight.
|
|
1176
|
+
*/
|
|
1177
|
+
declare const BasketLeg: z.ZodObject<{
|
|
1178
|
+
asset: z.ZodString;
|
|
1179
|
+
marginMode: z.ZodEnum<{
|
|
1180
|
+
isolated: "isolated";
|
|
1181
|
+
cross: "cross";
|
|
1182
|
+
}>;
|
|
1183
|
+
leverage: z.ZodString;
|
|
1184
|
+
side: z.ZodEnum<{
|
|
1185
|
+
BUY: "BUY";
|
|
1186
|
+
SELL: "SELL";
|
|
1187
|
+
}>;
|
|
1188
|
+
weight: z.ZodNumber;
|
|
1189
|
+
}, z.core.$strip>;
|
|
1190
|
+
type BasketLeg = z.infer<typeof BasketLeg>;
|
|
1191
|
+
declare const MaxBasketSizeInput: z.ZodObject<{
|
|
1192
|
+
legs: z.ZodArray<z.ZodObject<{
|
|
1193
|
+
asset: z.ZodString;
|
|
1194
|
+
marginMode: z.ZodEnum<{
|
|
1195
|
+
isolated: "isolated";
|
|
1196
|
+
cross: "cross";
|
|
1197
|
+
}>;
|
|
1198
|
+
leverage: z.ZodString;
|
|
1199
|
+
side: z.ZodEnum<{
|
|
1200
|
+
BUY: "BUY";
|
|
1201
|
+
SELL: "SELL";
|
|
1202
|
+
}>;
|
|
1203
|
+
weight: z.ZodNumber;
|
|
1204
|
+
}, z.core.$strip>>;
|
|
1205
|
+
}, z.core.$strip>;
|
|
1206
|
+
type MaxBasketSizeInput = z.infer<typeof MaxBasketSizeInput>;
|
|
1207
|
+
declare const MaxBasketSizeResult: z.ZodObject<{
|
|
1208
|
+
maxNotional: z.ZodNullable<z.ZodString>;
|
|
1209
|
+
legs: z.ZodArray<z.ZodObject<{
|
|
1210
|
+
asset: z.ZodString;
|
|
1211
|
+
notional: z.ZodString;
|
|
1212
|
+
marginRequired: z.ZodString;
|
|
1213
|
+
}, z.core.$strip>>;
|
|
1214
|
+
bindingConstraint: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1215
|
+
kind: z.ZodLiteral<"cross-pool">;
|
|
1216
|
+
pool: z.ZodString;
|
|
1217
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1218
|
+
kind: z.ZodLiteral<"isolated-leg">;
|
|
1219
|
+
asset: z.ZodString;
|
|
1220
|
+
}, z.core.$strip>], "kind">>;
|
|
1221
|
+
}, z.core.$strip>;
|
|
1222
|
+
type MaxBasketSizeResult = z.infer<typeof MaxBasketSizeResult>;
|
|
1223
|
+
/**
|
|
1224
|
+
* One basket leg with its leverage already capped by the venue adapter.
|
|
1225
|
+
*
|
|
1226
|
+
* `marginMode` does not enter the maths: an isolated leg gets dedicated margin, but that margin is
|
|
1227
|
+
* still transferred out of the same free balance, so it draws on the same budget as a cross leg.
|
|
1228
|
+
* It is carried so the caller passes its basket through unchanged.
|
|
1229
|
+
*/
|
|
1230
|
+
type CappedBasketLeg = {
|
|
848
1231
|
asset: string;
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
}
|
|
1232
|
+
/**
|
|
1233
|
+
* The collateral pool this leg's margin comes out of, as the venue adapter resolves it — a CEX
|
|
1234
|
+
* from the symbol's settlement currency, Hyperliquid from the dex's collateral token. Legs in
|
|
1235
|
+
* different pools cannot fund each other.
|
|
1236
|
+
*/
|
|
1237
|
+
pool: string;
|
|
1238
|
+
/** Unsigned, in the caller's own scale — `computeMaxBasketSize` normalises by Σweight. */
|
|
1239
|
+
weight: number;
|
|
1240
|
+
effectiveLeverage: string;
|
|
1241
|
+
marginMode: MarginMode;
|
|
1242
|
+
/** This leg's own venue ceiling in USD notional; `null` when the venue names no cap. */
|
|
1243
|
+
maxNotional: string | null;
|
|
1244
|
+
};
|
|
1245
|
+
/** The margin budget behind each collateral pool, plus the legs those pools must fund at once. */
|
|
1246
|
+
type MaxBasketSizeCalculation = {
|
|
1247
|
+
/**
|
|
1248
|
+
* Pool id to that pool's USD-equivalent budget. A pool whose collateral is not ~1 USD supplies no
|
|
1249
|
+
* entry until someone adds a price source, and a leg drawing on a missing entry voids the answer.
|
|
1250
|
+
*/
|
|
1251
|
+
budgets: Record<string, string>;
|
|
1252
|
+
legs: CappedBasketLeg[];
|
|
1253
|
+
};
|
|
1254
|
+
/**
|
|
1255
|
+
* The largest gross notional this basket can reach while every leg stays funded at its weight.
|
|
1256
|
+
*
|
|
1257
|
+
* Returns a null size when a pool behind the basket cannot be valued — never a zero, which a
|
|
1258
|
+
* consumer would read as "no collateral" rather than "not known". A basket whose own figures cannot
|
|
1259
|
+
* be sized (see `isSizeableInput`) gets the same null, so this call never throws and never returns a
|
|
1260
|
+
* result that fails `MaxBasketSizeResult`.
|
|
1261
|
+
*/
|
|
1262
|
+
declare function computeMaxBasketSize(input: MaxBasketSizeCalculation): MaxBasketSizeResult;
|
|
1263
|
+
|
|
871
1264
|
interface AccountPosition {
|
|
872
1265
|
symbol: string;
|
|
873
1266
|
side: 'long' | 'short' | 'both';
|
|
@@ -924,12 +1317,16 @@ interface AccountTracker {
|
|
|
924
1317
|
disconnect(): Promise<void>;
|
|
925
1318
|
snapshot(): Promise<AccountSnapshot>;
|
|
926
1319
|
snapshotAssets(coins: string[]): Promise<AssetSnapshotMap>;
|
|
1320
|
+
/** Sizes a basket over REST alone, so it stays usable without a running socket. */
|
|
1321
|
+
snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
927
1322
|
readonly isConnected: boolean;
|
|
928
1323
|
readonly isInitialized: boolean;
|
|
929
1324
|
readonly hasListeners: boolean;
|
|
930
1325
|
trackBalance(cb: BalanceCallback): () => void;
|
|
931
1326
|
trackPosition(cb: PositionsCallback): () => void;
|
|
932
1327
|
trackAsset(asset: string, cb: TrackedAssetCallback): () => void;
|
|
1328
|
+
/** Async: a basket may name assets this tracker has not subscribed to yet. */
|
|
1329
|
+
maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
933
1330
|
getBalance(): AccountBalance | null;
|
|
934
1331
|
getPositions(): AccountPosition[];
|
|
935
1332
|
getTrackedAsset(coin: string): TrackedAssetInfo | null;
|
|
@@ -970,6 +1367,9 @@ declare abstract class BaseAccountTracker implements AccountTracker {
|
|
|
970
1367
|
private broadcast;
|
|
971
1368
|
abstract start(): Promise<void>;
|
|
972
1369
|
abstract snapshot(): Promise<AccountSnapshot>;
|
|
1370
|
+
/** Every venue implements both sizing paths — the live one and the REST one. */
|
|
1371
|
+
abstract maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1372
|
+
abstract snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
973
1373
|
protected abstract fetchAssetSnapshots(coins: string[]): Promise<AssetSnapshotMap>;
|
|
974
1374
|
abstract get isConnected(): boolean;
|
|
975
1375
|
protected abstract ensureAssetTracked(asset: string): void;
|
|
@@ -977,6 +1377,51 @@ declare abstract class BaseAccountTracker implements AccountTracker {
|
|
|
977
1377
|
protected abstract cleanupConnections(): void | Promise<void>;
|
|
978
1378
|
}
|
|
979
1379
|
|
|
1380
|
+
/**
|
|
1381
|
+
* Binance's two account-mode balance variants.
|
|
1382
|
+
*
|
|
1383
|
+
* Core fields only, with `null` wherever a figure cannot be derived. What differs by mode is not the
|
|
1384
|
+
* shape but when the core scalars go null, which follows each mode's collateral-pool model. One
|
|
1385
|
+
* `z.literal` per mode, because `z.discriminatedUnion` needs a single literal tag per member rather
|
|
1386
|
+
* than a `z.enum` shorthand.
|
|
1387
|
+
*/
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* Single-asset mode runs one collateral pool per settlement currency, and Binance's account-level
|
|
1391
|
+
* figures cover USDT only there. Once a second pool is funded no account total exists to report, so
|
|
1392
|
+
* `totalEquity` goes null and `perCollateral` is the whole answer.
|
|
1393
|
+
*/
|
|
1394
|
+
declare const BinanceSingleAssetBalance: z.ZodObject<{
|
|
1395
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1396
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1397
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1398
|
+
poolsShared: z.ZodBoolean;
|
|
1399
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1400
|
+
asset: z.ZodString;
|
|
1401
|
+
equity: z.ZodString;
|
|
1402
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1403
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1404
|
+
}, z.core.$strip>>;
|
|
1405
|
+
timestamp: z.ZodNumber;
|
|
1406
|
+
accountMode: z.ZodLiteral<"binance:singleAsset">;
|
|
1407
|
+
}, z.core.$strip>;
|
|
1408
|
+
type BinanceSingleAssetBalance = z.infer<typeof BinanceSingleAssetBalance>;
|
|
1409
|
+
declare const BinanceMultiAssetBalance: z.ZodObject<{
|
|
1410
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1411
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1412
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1413
|
+
poolsShared: z.ZodBoolean;
|
|
1414
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1415
|
+
asset: z.ZodString;
|
|
1416
|
+
equity: z.ZodString;
|
|
1417
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1418
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1419
|
+
}, z.core.$strip>>;
|
|
1420
|
+
timestamp: z.ZodNumber;
|
|
1421
|
+
accountMode: z.ZodLiteral<"binance:multiAsset">;
|
|
1422
|
+
}, z.core.$strip>;
|
|
1423
|
+
type BinanceMultiAssetBalance = z.infer<typeof BinanceMultiAssetBalance>;
|
|
1424
|
+
|
|
980
1425
|
type BinanceAccountTrackerConfig = AccountTrackerConfig & {
|
|
981
1426
|
credentials: SupportedCredentials;
|
|
982
1427
|
listenKeyRefreshMs?: number;
|
|
@@ -993,10 +1438,19 @@ declare class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
993
1438
|
private listenKeyTimer;
|
|
994
1439
|
private pollTimer;
|
|
995
1440
|
private currentPositions;
|
|
996
|
-
private
|
|
1441
|
+
private accountMode;
|
|
997
1442
|
private trackedAssetInfos;
|
|
998
1443
|
constructor(config: BinanceAccountTrackerConfig);
|
|
999
1444
|
snapshot(): Promise<AccountSnapshot>;
|
|
1445
|
+
/**
|
|
1446
|
+
* Binance sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
|
|
1447
|
+
* `availableMargin` alone would ship a number no venue field backs. The missing input is
|
|
1448
|
+
* `/fapi/v2/positionRisk` → `maxNotionalValue` (the account's own per-symbol ceiling), with
|
|
1449
|
+
* `/fapi/v1/leverageBracket` behind it for the tier a larger size would fall into.
|
|
1450
|
+
*/
|
|
1451
|
+
maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1452
|
+
/** The REST path answers the same way — there is no size either way, not a slower one. */
|
|
1453
|
+
snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1000
1454
|
/**
|
|
1001
1455
|
* Stateless one-shot per-asset settings read: `positionRisk` with no symbol returns leverage +
|
|
1002
1456
|
* margin type for every symbol (positioned or not), so any number of assets costs one call.
|
|
@@ -1017,6 +1471,64 @@ declare class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
1017
1471
|
private refreshAllPositions;
|
|
1018
1472
|
}
|
|
1019
1473
|
|
|
1474
|
+
/**
|
|
1475
|
+
* Bybit's three account-mode balance variants.
|
|
1476
|
+
*
|
|
1477
|
+
* Core fields only — Bybit carries no per-mode detail yet, with `null` wherever a figure cannot
|
|
1478
|
+
* be derived. All three are unified-account modes sharing one margin pool, so the core scalars are
|
|
1479
|
+
* the whole answer and `perCollateral` only breaks them down — where Binance single-asset and OKX
|
|
1480
|
+
* Spot/Futures have to null those scalars once a second pool is funded. The mode still tags the
|
|
1481
|
+
* variant so detail can be added later without another breaking change. One `z.literal` per mode,
|
|
1482
|
+
* because `z.discriminatedUnion` needs a single literal tag per member rather than a `z.enum`
|
|
1483
|
+
* shorthand.
|
|
1484
|
+
*/
|
|
1485
|
+
|
|
1486
|
+
declare const BybitIsolatedMarginBalance: z.ZodObject<{
|
|
1487
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1488
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1489
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1490
|
+
poolsShared: z.ZodBoolean;
|
|
1491
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1492
|
+
asset: z.ZodString;
|
|
1493
|
+
equity: z.ZodString;
|
|
1494
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1495
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1496
|
+
}, z.core.$strip>>;
|
|
1497
|
+
timestamp: z.ZodNumber;
|
|
1498
|
+
accountMode: z.ZodLiteral<"bybit:isolatedMargin">;
|
|
1499
|
+
}, z.core.$strip>;
|
|
1500
|
+
type BybitIsolatedMarginBalance = z.infer<typeof BybitIsolatedMarginBalance>;
|
|
1501
|
+
declare const BybitRegularMarginBalance: z.ZodObject<{
|
|
1502
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1503
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1504
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1505
|
+
poolsShared: z.ZodBoolean;
|
|
1506
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1507
|
+
asset: z.ZodString;
|
|
1508
|
+
equity: z.ZodString;
|
|
1509
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1510
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1511
|
+
}, z.core.$strip>>;
|
|
1512
|
+
timestamp: z.ZodNumber;
|
|
1513
|
+
accountMode: z.ZodLiteral<"bybit:regularMargin">;
|
|
1514
|
+
}, z.core.$strip>;
|
|
1515
|
+
type BybitRegularMarginBalance = z.infer<typeof BybitRegularMarginBalance>;
|
|
1516
|
+
declare const BybitPortfolioMarginBalance: z.ZodObject<{
|
|
1517
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1518
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1519
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1520
|
+
poolsShared: z.ZodBoolean;
|
|
1521
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1522
|
+
asset: z.ZodString;
|
|
1523
|
+
equity: z.ZodString;
|
|
1524
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1525
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1526
|
+
}, z.core.$strip>>;
|
|
1527
|
+
timestamp: z.ZodNumber;
|
|
1528
|
+
accountMode: z.ZodLiteral<"bybit:portfolioMargin">;
|
|
1529
|
+
}, z.core.$strip>;
|
|
1530
|
+
type BybitPortfolioMarginBalance = z.infer<typeof BybitPortfolioMarginBalance>;
|
|
1531
|
+
|
|
1020
1532
|
type BybitAccountTrackerConfig = AccountTrackerConfig & {
|
|
1021
1533
|
credentials: SupportedCredentials;
|
|
1022
1534
|
};
|
|
@@ -1027,10 +1539,25 @@ declare class BybitAccountTracker extends BaseAccountTracker {
|
|
|
1027
1539
|
private openListenerId;
|
|
1028
1540
|
private rawCoins;
|
|
1029
1541
|
private lastWallet;
|
|
1030
|
-
private
|
|
1542
|
+
private accountMode;
|
|
1543
|
+
private withdrawable;
|
|
1544
|
+
private lastWithdrawableReadAt;
|
|
1545
|
+
private withdrawableRefreshTimer;
|
|
1546
|
+
private withdrawableReadInFlight;
|
|
1547
|
+
private withdrawableReadPending;
|
|
1548
|
+
private lifecycleVersion;
|
|
1031
1549
|
private trackedAssetInfos;
|
|
1032
1550
|
constructor(config: BybitAccountTrackerConfig);
|
|
1033
1551
|
snapshot(): Promise<AccountSnapshot>;
|
|
1552
|
+
/**
|
|
1553
|
+
* Bybit sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
|
|
1554
|
+
* `availableMargin` alone would ship a number no venue field backs. The missing input is
|
|
1555
|
+
* `/v5/position/list` → `leverage` (the account's own per-symbol setting), with
|
|
1556
|
+
* `/v5/market/risk-limit` → `maxLeverage` behind it for the tier a larger size would fall into.
|
|
1557
|
+
*/
|
|
1558
|
+
maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1559
|
+
/** The REST path answers the same way — there is no size either way, not a slower one. */
|
|
1560
|
+
snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1034
1561
|
/**
|
|
1035
1562
|
* Stateless one-shot per-asset settings read. Bybit has no batch leverage endpoint, but
|
|
1036
1563
|
* `position/list` by settleCoin returns every open position (with leverage) in one call, so
|
|
@@ -1044,15 +1571,232 @@ declare class BybitAccountTracker extends BaseAccountTracker {
|
|
|
1044
1571
|
protected cleanupConnections(): Promise<void>;
|
|
1045
1572
|
get isConnected(): boolean;
|
|
1046
1573
|
private fetchSnapshotData;
|
|
1574
|
+
/**
|
|
1575
|
+
* Read how much can leave the trading account, for the coins the wallet payload lists.
|
|
1576
|
+
*
|
|
1577
|
+
* Best-effort on purpose: this is a second signed call that a read-only key may be refused, and
|
|
1578
|
+
* a refusal must cost the caller a `null` field rather than the whole balance.
|
|
1579
|
+
*
|
|
1580
|
+
* A refusal is reported as `failed` rather than as an empty answer, because only the caller knows
|
|
1581
|
+
* what to do with it: the snapshot path has no earlier figure and reports nothing known, while
|
|
1582
|
+
* the live path keeps the figure its last successful read published.
|
|
1583
|
+
*/
|
|
1584
|
+
private readWithdrawable;
|
|
1047
1585
|
protected ensureAssetTracked(coin: string): void;
|
|
1048
1586
|
protected releaseAsset(coin: string): void;
|
|
1049
1587
|
private subscribe;
|
|
1050
1588
|
private handleInitialData;
|
|
1051
1589
|
private routeRaw;
|
|
1052
1590
|
private handleMessage;
|
|
1591
|
+
/**
|
|
1592
|
+
* Fold one wallet push into the whole account, then publish what that whole account says.
|
|
1593
|
+
*
|
|
1594
|
+
* Bybit pushes only what moved: an update names the coins whose figures changed and leaves every
|
|
1595
|
+
* other coin out. So the coin list is taken from the per-coin merge rather than from the push,
|
|
1596
|
+
* and everything read off it sees every coin the account holds — the published rows, and the
|
|
1597
|
+
* coin list the next transferable-amount read asks about. A push naming one of two funded coins
|
|
1598
|
+
* would otherwise drop the other's row and let its per-coin maximum answer for the account.
|
|
1599
|
+
*
|
|
1600
|
+
* The account-level figures inherit on `??`, never on `||`, because ABSENT and BLANK say
|
|
1601
|
+
* opposite things here. A field this push left out was not restated and its previous value still
|
|
1602
|
+
* stands; a field present as `''` is Bybit withdrawing the figure, which it does for
|
|
1603
|
+
* `totalAvailableBalance` among others. Inheriting a blank would republish a number the venue no
|
|
1604
|
+
* longer states, and it would do it BEHIND `decimalOrNull`, whose whole job is to publish a blank
|
|
1605
|
+
* as `null`: overwriting the blank here means that guard never sees it.
|
|
1606
|
+
*/
|
|
1053
1607
|
private handleWalletUpdate;
|
|
1608
|
+
/** Publish the balance built from the newest wallet payload and the cached transferable amounts. */
|
|
1609
|
+
private emitBalance;
|
|
1610
|
+
/**
|
|
1611
|
+
* Queue the next transferable-amount read, no sooner than the venue's own rate limit allows.
|
|
1612
|
+
*
|
|
1613
|
+
* Nothing waits on it: the wallet update is already published from the cached figure. One queued
|
|
1614
|
+
* read covers every wallet tick that lands before it runs, which is what stops a burst of ticks
|
|
1615
|
+
* becoming a burst of signed calls — and because a tick always leaves a read queued or marked
|
|
1616
|
+
* pending, a moved figure is still picked up within one interval rather than dropped.
|
|
1617
|
+
*/
|
|
1618
|
+
private refreshWithdrawableSoon;
|
|
1619
|
+
/**
|
|
1620
|
+
* Hold one transferable-amount read open at a time, and queue the ticks that arrive during it.
|
|
1621
|
+
*
|
|
1622
|
+
* Serialising the reads is what keeps the published figure the newest one: two overlapping reads
|
|
1623
|
+
* can come back in either order, and the older answer landing last would publish an amount the
|
|
1624
|
+
* venue has already moved past.
|
|
1625
|
+
*/
|
|
1626
|
+
private refreshWithdrawableBalance;
|
|
1627
|
+
/**
|
|
1628
|
+
* Re-read the transferable amount behind the live path, then re-publish only if it moved.
|
|
1629
|
+
*
|
|
1630
|
+
* Fire-and-forget: the wallet update is already published with the previous figure, so a slow
|
|
1631
|
+
* read delays the correction instead of blocking the balance. A read that FAILS changes nothing
|
|
1632
|
+
* at all — the last good figure stays published, because a refusal says Bybit did not answer,
|
|
1633
|
+
* not that the account has nothing to transfer. Both the read and the re-publish take the NEWEST
|
|
1634
|
+
* wallet rather than the one that queued them, so a wallet update that landed meanwhile is
|
|
1635
|
+
* neither missed nor rolled back.
|
|
1636
|
+
*/
|
|
1637
|
+
private performWithdrawableRefresh;
|
|
1054
1638
|
}
|
|
1055
1639
|
|
|
1640
|
+
/**
|
|
1641
|
+
* Hyperliquid's three account-mode balance variants.
|
|
1642
|
+
*
|
|
1643
|
+
* Hyperliquid has the most divergent risk model of the five venues, so each mode carries its own
|
|
1644
|
+
* figures rather than sharing one flat shape. HIP-3 dexes can share the main dex's collateral
|
|
1645
|
+
* token, so every account-level figure aggregates across dexes and the per-dex list is kept
|
|
1646
|
+
* alongside — the aggregate hides HIP-3 positions entirely.
|
|
1647
|
+
*
|
|
1648
|
+
* Every figure derived from a spot price is nullable, because a spot balance carries only a token
|
|
1649
|
+
* index and no route to USDC reaches every token. The `perCollateral` rows are not:
|
|
1650
|
+
* a row is a quantity of one collateral token in that token's own units, so it keeps working
|
|
1651
|
+
* precisely because it is never converted.
|
|
1652
|
+
*/
|
|
1653
|
+
|
|
1654
|
+
declare const HyperliquidDexState: z.ZodObject<{
|
|
1655
|
+
dex: z.ZodString;
|
|
1656
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
1657
|
+
accountValue: z.ZodString;
|
|
1658
|
+
crossNotional: z.ZodString;
|
|
1659
|
+
crossMaintenanceMargin: z.ZodString;
|
|
1660
|
+
withdrawable: z.ZodString;
|
|
1661
|
+
}, z.core.$strip>;
|
|
1662
|
+
type HyperliquidDexState = z.infer<typeof HyperliquidDexState>;
|
|
1663
|
+
declare const HyperliquidStandardBalance: z.ZodObject<{
|
|
1664
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1665
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1666
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1667
|
+
poolsShared: z.ZodBoolean;
|
|
1668
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1669
|
+
asset: z.ZodString;
|
|
1670
|
+
equity: z.ZodString;
|
|
1671
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1672
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1673
|
+
}, z.core.$strip>>;
|
|
1674
|
+
timestamp: z.ZodNumber;
|
|
1675
|
+
accountMode: z.ZodLiteral<"hyperliquid:standard">;
|
|
1676
|
+
spotEquity: z.ZodNullable<z.ZodString>;
|
|
1677
|
+
perpsEquity: z.ZodString;
|
|
1678
|
+
vaultEquity: z.ZodString;
|
|
1679
|
+
stakedEquity: z.ZodNullable<z.ZodString>;
|
|
1680
|
+
unrealizedPnl: z.ZodString;
|
|
1681
|
+
maintenanceMargin: z.ZodString;
|
|
1682
|
+
crossMarginRatio: z.ZodString;
|
|
1683
|
+
crossAccountLeverage: z.ZodString;
|
|
1684
|
+
perDexState: z.ZodArray<z.ZodObject<{
|
|
1685
|
+
dex: z.ZodString;
|
|
1686
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
1687
|
+
accountValue: z.ZodString;
|
|
1688
|
+
crossNotional: z.ZodString;
|
|
1689
|
+
crossMaintenanceMargin: z.ZodString;
|
|
1690
|
+
withdrawable: z.ZodString;
|
|
1691
|
+
}, z.core.$strip>>;
|
|
1692
|
+
}, z.core.$strip>;
|
|
1693
|
+
type HyperliquidStandardBalance = z.infer<typeof HyperliquidStandardBalance>;
|
|
1694
|
+
declare const HyperliquidUnifiedBalance: z.ZodObject<{
|
|
1695
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1696
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1697
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1698
|
+
poolsShared: z.ZodBoolean;
|
|
1699
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1700
|
+
asset: z.ZodString;
|
|
1701
|
+
equity: z.ZodString;
|
|
1702
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1703
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1704
|
+
}, z.core.$strip>>;
|
|
1705
|
+
timestamp: z.ZodNumber;
|
|
1706
|
+
accountMode: z.ZodLiteral<"hyperliquid:unified">;
|
|
1707
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
1708
|
+
vaultEquity: z.ZodString;
|
|
1709
|
+
stakedEquity: z.ZodNullable<z.ZodString>;
|
|
1710
|
+
portfolioValue: z.ZodNullable<z.ZodString>;
|
|
1711
|
+
unrealizedPnl: z.ZodString;
|
|
1712
|
+
perpsMaintenanceMargin: z.ZodString;
|
|
1713
|
+
unifiedAccountRatio: z.ZodString;
|
|
1714
|
+
unifiedAccountLeverage: z.ZodNullable<z.ZodString>;
|
|
1715
|
+
perDexState: z.ZodArray<z.ZodObject<{
|
|
1716
|
+
dex: z.ZodString;
|
|
1717
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
1718
|
+
accountValue: z.ZodString;
|
|
1719
|
+
crossNotional: z.ZodString;
|
|
1720
|
+
crossMaintenanceMargin: z.ZodString;
|
|
1721
|
+
withdrawable: z.ZodString;
|
|
1722
|
+
}, z.core.$strip>>;
|
|
1723
|
+
}, z.core.$strip>;
|
|
1724
|
+
type HyperliquidUnifiedBalance = z.infer<typeof HyperliquidUnifiedBalance>;
|
|
1725
|
+
/**
|
|
1726
|
+
* One Portfolio Margin spot holding, as the venue's own balances table states it.
|
|
1727
|
+
*
|
|
1728
|
+
* PM widens the shared `CollateralBalance` in two ways it cannot carry, which is why this variant
|
|
1729
|
+
* declares its own row type rather than reusing it:
|
|
1730
|
+
*
|
|
1731
|
+
* - **the figures are SIGNED.** A borrowed coin holds a negative `total`, and seven of the fourteen
|
|
1732
|
+
* accounts measured hold one — `0x0871deb3…` reports USDC at −957,802.15. An unsigned row cannot
|
|
1733
|
+
* state that at all, which is the defect that made a borrowed pool indistinguishable from an
|
|
1734
|
+
* untouched one.
|
|
1735
|
+
* - **two more columns.** `ltv` and `borrowCapUsed` are per-coin risk weights the venue renders
|
|
1736
|
+
* beside the quantities, and both are PM-only wire fields.
|
|
1737
|
+
*
|
|
1738
|
+
* The row is otherwise the shared shape: same keys, same meanings, so a consumer reading
|
|
1739
|
+
* `perCollateral` without narrowing still reads `asset` / `equity` / `availableMargin` /
|
|
1740
|
+
* `withdrawable` off every venue.
|
|
1741
|
+
*/
|
|
1742
|
+
declare const HyperliquidPortfolioMarginCollateral: z.ZodObject<{
|
|
1743
|
+
asset: z.ZodString;
|
|
1744
|
+
equity: z.ZodString;
|
|
1745
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1746
|
+
withdrawable: z.ZodString;
|
|
1747
|
+
ltv: z.ZodNullable<z.ZodString>;
|
|
1748
|
+
borrowCapUsed: z.ZodNullable<z.ZodString>;
|
|
1749
|
+
}, z.core.$strip>;
|
|
1750
|
+
type HyperliquidPortfolioMarginCollateral = z.infer<typeof HyperliquidPortfolioMarginCollateral>;
|
|
1751
|
+
declare const HyperliquidPortfolioMarginBalance: z.ZodObject<{
|
|
1752
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1753
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1754
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1755
|
+
poolsShared: z.ZodBoolean;
|
|
1756
|
+
timestamp: z.ZodNumber;
|
|
1757
|
+
accountMode: z.ZodLiteral<"hyperliquid:portfolioMargin">;
|
|
1758
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1759
|
+
asset: z.ZodString;
|
|
1760
|
+
equity: z.ZodString;
|
|
1761
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1762
|
+
withdrawable: z.ZodString;
|
|
1763
|
+
ltv: z.ZodNullable<z.ZodString>;
|
|
1764
|
+
borrowCapUsed: z.ZodNullable<z.ZodString>;
|
|
1765
|
+
}, z.core.$strip>>;
|
|
1766
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
1767
|
+
vaultEquity: z.ZodString;
|
|
1768
|
+
stakedEquity: z.ZodNullable<z.ZodString>;
|
|
1769
|
+
portfolioValue: z.ZodNullable<z.ZodString>;
|
|
1770
|
+
unrealizedPnl: z.ZodString;
|
|
1771
|
+
perpsMaintenanceMargin: z.ZodString;
|
|
1772
|
+
portfolioMarginRatio: z.ZodNullable<z.ZodString>;
|
|
1773
|
+
portfolioAccountLeverage: z.ZodNullable<z.ZodString>;
|
|
1774
|
+
borrowCapUsed: z.ZodNullable<z.ZodString>;
|
|
1775
|
+
perDexState: z.ZodArray<z.ZodObject<{
|
|
1776
|
+
dex: z.ZodString;
|
|
1777
|
+
collateralToken: z.ZodNullable<z.ZodNumber>;
|
|
1778
|
+
accountValue: z.ZodString;
|
|
1779
|
+
crossNotional: z.ZodString;
|
|
1780
|
+
crossMaintenanceMargin: z.ZodString;
|
|
1781
|
+
withdrawable: z.ZodString;
|
|
1782
|
+
}, z.core.$strip>>;
|
|
1783
|
+
}, z.core.$strip>;
|
|
1784
|
+
type HyperliquidPortfolioMarginBalance = z.infer<typeof HyperliquidPortfolioMarginBalance>;
|
|
1785
|
+
|
|
1786
|
+
/**
|
|
1787
|
+
* Hyperliquid's two read paths: the live WebSocket tracker and the one-shot REST snapshot.
|
|
1788
|
+
*
|
|
1789
|
+
* Both fill the same `HyperliquidBalanceContext` and hand it to the same mapper, which is what
|
|
1790
|
+
* makes "same account state, same balance" true across two different transports. The tracker takes
|
|
1791
|
+
* every CHANGING value off a channel — `allDexsClearinghouseState`, `spotState`, `webData3`,
|
|
1792
|
+
* `allMids`, `activeAssetData` — including vault equity, which rides `webData3`. Its only REST
|
|
1793
|
+
* reads happen at `start()`: the static dex metadata, and the staking position, which the venue
|
|
1794
|
+
* publishes on no channel at all.
|
|
1795
|
+
*
|
|
1796
|
+
* The snapshot has no channels, so it reads the same figures over REST — vault equity from
|
|
1797
|
+
* `userVaultEquities`, which was measured equal to the `webData3` figure on ten live accounts.
|
|
1798
|
+
*/
|
|
1799
|
+
|
|
1056
1800
|
type HyperliquidAccountTrackerConfig = AccountTrackerConfig & {
|
|
1057
1801
|
account: TradeAccount;
|
|
1058
1802
|
credentials: SupportedCredentials;
|
|
@@ -1066,17 +1810,33 @@ declare class HyperliquidAccountTracker extends BaseAccountTracker {
|
|
|
1066
1810
|
private subscribedCoins;
|
|
1067
1811
|
private lastSummary;
|
|
1068
1812
|
private spotCoinBalances;
|
|
1813
|
+
/** Portfolio Margin's own risk scalars, which ride the same `spotState` frame the balances do. */
|
|
1814
|
+
private portfolioMarginRatio;
|
|
1815
|
+
private borrowRatioByToken;
|
|
1069
1816
|
private hasSpotState;
|
|
1070
1817
|
private hasClearinghouseState;
|
|
1071
1818
|
private accountType;
|
|
1072
|
-
private
|
|
1819
|
+
private spotMeta;
|
|
1820
|
+
private collateralTokenNames;
|
|
1821
|
+
private prices;
|
|
1822
|
+
private hasWebData3;
|
|
1823
|
+
private vaultEquity;
|
|
1824
|
+
private stakedHype;
|
|
1073
1825
|
private dexToMeta;
|
|
1074
1826
|
private trackedAssetData;
|
|
1075
1827
|
constructor(config: HyperliquidAccountTrackerConfig);
|
|
1076
1828
|
/**
|
|
1077
|
-
* Reads account mode, collateral balances, per-DEX state,
|
|
1829
|
+
* Reads account mode, spot prices, collateral balances, per-DEX state, staking, vaults and
|
|
1830
|
+
* per-asset headroom without opening a socket.
|
|
1078
1831
|
*/
|
|
1079
1832
|
snapshot(): Promise<AccountSnapshot>;
|
|
1833
|
+
/** Sizes a basket over REST alone, so the call stays usable without a running socket. */
|
|
1834
|
+
snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1835
|
+
/**
|
|
1836
|
+
* Sizes a basket against live state, fetching per-asset data for any leg the socket has not
|
|
1837
|
+
* subscribed to — which is exactly why the call is asynchronous on both paths.
|
|
1838
|
+
*/
|
|
1839
|
+
maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1080
1840
|
/**
|
|
1081
1841
|
* Stateless one-shot per-asset settings read via the `activeAssetData` info request (the REST
|
|
1082
1842
|
* twin of the live WS subscription), one request per coin fired in parallel — the info endpoint
|
|
@@ -1100,41 +1860,120 @@ declare class HyperliquidAccountTracker extends BaseAccountTracker {
|
|
|
1100
1860
|
private routeRaw;
|
|
1101
1861
|
private handle;
|
|
1102
1862
|
private loadPerpMetas;
|
|
1863
|
+
/** Loads the dex metadata a sizing call needs, reusing whatever `start()` already cached. */
|
|
1864
|
+
private loadPerpMetasOnce;
|
|
1865
|
+
/** Loads the token names a pool id is spelled with, reusing whatever `start()` already cached. */
|
|
1866
|
+
private loadCollateralTokenNamesOnce;
|
|
1867
|
+
/** Reads `activeAssetData` for each coin in parallel, dropping the coins the venue refuses. */
|
|
1868
|
+
private fetchActiveAssetEvents;
|
|
1869
|
+
/** The asset set `availableMargin` is the floor over: the locked coins plus every tracked one. */
|
|
1870
|
+
private coinsForAvailableMargin;
|
|
1103
1871
|
private onClearinghouseState;
|
|
1104
1872
|
private onActiveAssetData;
|
|
1873
|
+
private onAllMids;
|
|
1105
1874
|
private onWebData3;
|
|
1106
1875
|
private onSpotState;
|
|
1876
|
+
/**
|
|
1877
|
+
* Builds the live balance once every channel that feeds it has reported, or `undefined` until then.
|
|
1878
|
+
*
|
|
1879
|
+
* All four are required. Every mode now values the spot wallet, so a balance emitted before
|
|
1880
|
+
* `spotState` and `allMids` would report equity missing its whole spot half; and one emitted
|
|
1881
|
+
* before `webData3` would report vault equity as zero on an account that holds millions in a
|
|
1882
|
+
* vault. Partial equity is worse than no equity, so nothing is published early.
|
|
1883
|
+
*/
|
|
1107
1884
|
private buildBalance;
|
|
1885
|
+
/** The floor of `availableToTrade` over the tracked set; `null` when nothing is tracked. */
|
|
1886
|
+
private availableMargin;
|
|
1108
1887
|
/** Clears both sides of the live balance join and the public account cache without emitting. */
|
|
1109
1888
|
private resetLiveAccountState;
|
|
1110
1889
|
private buildTrackedAssetsMap;
|
|
1111
1890
|
}
|
|
1112
1891
|
|
|
1892
|
+
/**
|
|
1893
|
+
* Lighter's two account-mode balance variants.
|
|
1894
|
+
*
|
|
1895
|
+
* Classic is Unified minus `portfolioMargin`, so both modes share one field block.
|
|
1896
|
+
*/
|
|
1897
|
+
|
|
1898
|
+
declare const LighterClassicBalance: z.ZodObject<{
|
|
1899
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1900
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1901
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1902
|
+
poolsShared: z.ZodBoolean;
|
|
1903
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1904
|
+
asset: z.ZodString;
|
|
1905
|
+
equity: z.ZodString;
|
|
1906
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1907
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1908
|
+
}, z.core.$strip>>;
|
|
1909
|
+
timestamp: z.ZodNumber;
|
|
1910
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
1911
|
+
perpetualsEquity: z.ZodNullable<z.ZodString>;
|
|
1912
|
+
spotEquity: z.ZodNullable<z.ZodString>;
|
|
1913
|
+
publicPoolsEquity: z.ZodNullable<z.ZodString>;
|
|
1914
|
+
stakingEquity: z.ZodNullable<z.ZodString>;
|
|
1915
|
+
creditedInLit: z.ZodNullable<z.ZodString>;
|
|
1916
|
+
unrealizedPnl: z.ZodNullable<z.ZodString>;
|
|
1917
|
+
crossLeverage: z.ZodNullable<z.ZodString>;
|
|
1918
|
+
maintenanceMargin: z.ZodNullable<z.ZodString>;
|
|
1919
|
+
crossMarginUsage: z.ZodNullable<z.ZodString>;
|
|
1920
|
+
crossMarginRatio: z.ZodNullable<z.ZodString>;
|
|
1921
|
+
accountMode: z.ZodLiteral<"lighter:classic">;
|
|
1922
|
+
}, z.core.$strip>;
|
|
1923
|
+
type LighterClassicBalance = z.infer<typeof LighterClassicBalance>;
|
|
1924
|
+
declare const LighterUnifiedBalance: z.ZodObject<{
|
|
1925
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
1926
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
1927
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1928
|
+
poolsShared: z.ZodBoolean;
|
|
1929
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
1930
|
+
asset: z.ZodString;
|
|
1931
|
+
equity: z.ZodString;
|
|
1932
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
1933
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
1934
|
+
}, z.core.$strip>>;
|
|
1935
|
+
timestamp: z.ZodNumber;
|
|
1936
|
+
portfolioMargin: z.ZodNullable<z.ZodString>;
|
|
1937
|
+
tradingEquity: z.ZodNullable<z.ZodString>;
|
|
1938
|
+
perpetualsEquity: z.ZodNullable<z.ZodString>;
|
|
1939
|
+
spotEquity: z.ZodNullable<z.ZodString>;
|
|
1940
|
+
publicPoolsEquity: z.ZodNullable<z.ZodString>;
|
|
1941
|
+
stakingEquity: z.ZodNullable<z.ZodString>;
|
|
1942
|
+
creditedInLit: z.ZodNullable<z.ZodString>;
|
|
1943
|
+
unrealizedPnl: z.ZodNullable<z.ZodString>;
|
|
1944
|
+
crossLeverage: z.ZodNullable<z.ZodString>;
|
|
1945
|
+
maintenanceMargin: z.ZodNullable<z.ZodString>;
|
|
1946
|
+
crossMarginUsage: z.ZodNullable<z.ZodString>;
|
|
1947
|
+
crossMarginRatio: z.ZodNullable<z.ZodString>;
|
|
1948
|
+
accountMode: z.ZodLiteral<"lighter:unified">;
|
|
1949
|
+
}, z.core.$strip>;
|
|
1950
|
+
type LighterUnifiedBalance = z.infer<typeof LighterUnifiedBalance>;
|
|
1951
|
+
|
|
1113
1952
|
type LighterAccountTrackerConfig = AccountTrackerConfig & {
|
|
1114
1953
|
account: TradeAccount;
|
|
1115
1954
|
credentials: SupportedCredentials;
|
|
1116
|
-
sdk?: PearSDK;
|
|
1117
1955
|
};
|
|
1118
1956
|
declare class LighterAccountTracker extends BaseAccountTracker {
|
|
1119
1957
|
private readonly accountIdentifier;
|
|
1120
|
-
private readonly sdk;
|
|
1121
1958
|
private ws;
|
|
1122
1959
|
private messageListenerId;
|
|
1123
1960
|
private openListenerId;
|
|
1124
|
-
private
|
|
1125
|
-
private
|
|
1961
|
+
private positionPollTimer;
|
|
1962
|
+
private positionPollInFlight;
|
|
1963
|
+
private marketRefreshTimer;
|
|
1964
|
+
private marketRefreshInFlight;
|
|
1126
1965
|
private startInFlight;
|
|
1127
1966
|
private lifecycleVersion;
|
|
1128
1967
|
private stateVersion;
|
|
1129
1968
|
private assetsByAssetId;
|
|
1130
|
-
private
|
|
1969
|
+
private wsPositionsByMarketId;
|
|
1131
1970
|
private marketsByMarketId;
|
|
1132
|
-
private
|
|
1133
|
-
private
|
|
1134
|
-
private
|
|
1971
|
+
private marketsBySymbol;
|
|
1972
|
+
private spotPriceBySymbol;
|
|
1973
|
+
private stats;
|
|
1135
1974
|
private hasAssets;
|
|
1136
1975
|
constructor(config: LighterAccountTrackerConfig);
|
|
1137
|
-
/** Stateless one-shot account read
|
|
1976
|
+
/** Stateless one-shot account read — public endpoints only, and no websocket. */
|
|
1138
1977
|
snapshot(): Promise<AccountSnapshot>;
|
|
1139
1978
|
/**
|
|
1140
1979
|
* Stateless one-shot per-asset settings read, keyed by market id (the same identifier the live
|
|
@@ -1143,6 +1982,10 @@ declare class LighterAccountTracker extends BaseAccountTracker {
|
|
|
1143
1982
|
* supplies the exchange default for markets absent from the account payload.
|
|
1144
1983
|
*/
|
|
1145
1984
|
protected fetchAssetSnapshots(marketIds: string[]): Promise<AssetSnapshotMap>;
|
|
1985
|
+
/** Sizes a basket against the live account state, falling back to REST before the socket is up. */
|
|
1986
|
+
maxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1987
|
+
/** Sizes a basket over REST alone, so the answer needs no running socket. */
|
|
1988
|
+
snapshotMaxBasketSize(input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1146
1989
|
start(): Promise<void>;
|
|
1147
1990
|
/** Creates one tracker lifecycle while repeated callers share the same pending start. */
|
|
1148
1991
|
private performStart;
|
|
@@ -1156,15 +1999,148 @@ declare class LighterAccountTracker extends BaseAccountTracker {
|
|
|
1156
1999
|
private routeRaw;
|
|
1157
2000
|
private handle;
|
|
1158
2001
|
private onAccountAll;
|
|
2002
|
+
/** Keeps both published scopes: cross drives every "Cross" field, total drives the account ones. */
|
|
1159
2003
|
private onUserStats;
|
|
2004
|
+
/**
|
|
2005
|
+
* The account's balance, built from websocket state alone.
|
|
2006
|
+
*
|
|
2007
|
+
* Every input is websocket-sourced — `user_stats` for the two account scopes, `account_all` for
|
|
2008
|
+
* the assets and positions — except the market context, which is venue-wide metadata this
|
|
2009
|
+
* tracker re-reads on its own timer. This is the ONLY producer of the value `getBalance()`
|
|
2010
|
+
* returns while the tracker is running; `snapshot()` is the separate REST path and never writes
|
|
2011
|
+
* here.
|
|
2012
|
+
*
|
|
2013
|
+
* Null until both channels have delivered a frame, because a balance built from one of them
|
|
2014
|
+
* would be missing half the account.
|
|
2015
|
+
*/
|
|
1160
2016
|
private buildBalance;
|
|
2017
|
+
/** The market data both read paths join account state against, as the latest read left it. */
|
|
2018
|
+
private marketContext;
|
|
2019
|
+
/** The account's current per-market settings as the base tracker already holds them. */
|
|
2020
|
+
private liveAccountSettings;
|
|
1161
2021
|
private fetchPrimaryAccount;
|
|
1162
|
-
private
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
2022
|
+
private pollPositions;
|
|
2023
|
+
/**
|
|
2024
|
+
* Republishes positions and per-market settings from REST.
|
|
2025
|
+
*
|
|
2026
|
+
* Deliberately publishes NO balance. Every field of both Lighter variants comes off the two
|
|
2027
|
+
* websocket channels — `user_stats` carries both account scopes and `account_all` carries the
|
|
2028
|
+
* assets and positions behind them — so a REST balance here would only overwrite a live value
|
|
2029
|
+
* with an equal one, while making `getBalance()` REST-derived most of the time.
|
|
2030
|
+
*
|
|
2031
|
+
* It also leaves `wsPositionsByMarketId` alone. That store feeds the live balance's unrealized
|
|
2032
|
+
* PnL and maintenance margin, so writing REST rows into it would make a balance labelled live
|
|
2033
|
+
* partly REST-derived without any reader being able to tell.
|
|
2034
|
+
*/
|
|
2035
|
+
private performPositionPoll;
|
|
2036
|
+
/** Shares one in-flight market read, so a slow response cannot stack requests behind the WAF. */
|
|
2037
|
+
private refreshMarkets;
|
|
2038
|
+
/**
|
|
2039
|
+
* Re-reads the venue's markets and republishes the balance they move.
|
|
2040
|
+
*
|
|
2041
|
+
* `spotEquity` values each holding at the last trade its own spot book printed, so an index read
|
|
2042
|
+
* only at `start()` values a session-long tracker at session-old prices — and every scalar built
|
|
2043
|
+
* on it drifts with it.
|
|
2044
|
+
*
|
|
2045
|
+
* The perp books ride along, which is what closes the gap `toPositionRisks` documents: a market
|
|
2046
|
+
* Lighter listed after `start()` was unknown to the balance for the rest of the session, so a
|
|
2047
|
+
* position on it left the maintenance figure unknown for just as long. The read already carries
|
|
2048
|
+
* them, so learning them costs nothing. Their risk parameters come along as a consequence, which
|
|
2049
|
+
* only makes a slowly-moving margin fraction current rather than session-old.
|
|
2050
|
+
*
|
|
2051
|
+
* Perp books are UPSERTED, never replaced. An account can still hold a position on a market that
|
|
2052
|
+
* has dropped out of the listing, and the parameters this tracker last saw price that position —
|
|
2053
|
+
* where forgetting the market would stop pricing it at all.
|
|
2054
|
+
*
|
|
2055
|
+
* A read that fails, or that comes back carrying no spot books at all, leaves the last good price
|
|
2056
|
+
* index in place. Stale prices still value the account; an empty index would null every spot
|
|
2057
|
+
* figure the account has at once, which is a worse answer than a slightly old one.
|
|
2058
|
+
*
|
|
2059
|
+
* Only the market data moves here. A newly listed market's exchange-default asset settings reach
|
|
2060
|
+
* `trackAsset` consumers on the next websocket epoch, where `handleWsOpen` already republishes
|
|
2061
|
+
* them for every known market — publishing them here would overwrite the account's own settings.
|
|
2062
|
+
*/
|
|
2063
|
+
private performMarketRefresh;
|
|
1166
2064
|
}
|
|
1167
2065
|
|
|
2066
|
+
/**
|
|
2067
|
+
* OKX's four account-mode balance variants.
|
|
2068
|
+
*
|
|
2069
|
+
* Core fields only, with `null` wherever a figure cannot be derived. OKX publishes no account-level
|
|
2070
|
+
* margin fields in Futures mode (`acctLv=2`) at all, which is exactly why the flat shape had to go
|
|
2071
|
+
* — and why `perCollateral` matters most there, since `details[].availEq` is per currency. What
|
|
2072
|
+
* differs by mode is not the shape but when the core scalars go null, which follows each mode's
|
|
2073
|
+
* collateral-pool model. One `z.literal` per mode, because `z.discriminatedUnion` needs a single
|
|
2074
|
+
* literal tag per member rather than a `z.enum` shorthand.
|
|
2075
|
+
*/
|
|
2076
|
+
|
|
2077
|
+
/**
|
|
2078
|
+
* Spot and Futures mode run one collateral pool per currency, so `totalEq` is a USD total across
|
|
2079
|
+
* budgets that cannot fund each other. Once a second pool is funded there is no spendable account
|
|
2080
|
+
* total, so `totalEquity` goes null and `perCollateral` is the whole answer. `OkxFuturesBalance`
|
|
2081
|
+
* carries the same rule.
|
|
2082
|
+
*/
|
|
2083
|
+
declare const OkxSpotBalance: z.ZodObject<{
|
|
2084
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
2085
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
2086
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2087
|
+
poolsShared: z.ZodBoolean;
|
|
2088
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
2089
|
+
asset: z.ZodString;
|
|
2090
|
+
equity: z.ZodString;
|
|
2091
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2092
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
2093
|
+
}, z.core.$strip>>;
|
|
2094
|
+
timestamp: z.ZodNumber;
|
|
2095
|
+
accountMode: z.ZodLiteral<"okx:spot">;
|
|
2096
|
+
}, z.core.$strip>;
|
|
2097
|
+
type OkxSpotBalance = z.infer<typeof OkxSpotBalance>;
|
|
2098
|
+
declare const OkxFuturesBalance: z.ZodObject<{
|
|
2099
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
2100
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
2101
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2102
|
+
poolsShared: z.ZodBoolean;
|
|
2103
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
2104
|
+
asset: z.ZodString;
|
|
2105
|
+
equity: z.ZodString;
|
|
2106
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2107
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
2108
|
+
}, z.core.$strip>>;
|
|
2109
|
+
timestamp: z.ZodNumber;
|
|
2110
|
+
accountMode: z.ZodLiteral<"okx:futures">;
|
|
2111
|
+
}, z.core.$strip>;
|
|
2112
|
+
type OkxFuturesBalance = z.infer<typeof OkxFuturesBalance>;
|
|
2113
|
+
declare const OkxMultiCurrencyMarginBalance: z.ZodObject<{
|
|
2114
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
2115
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
2116
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2117
|
+
poolsShared: z.ZodBoolean;
|
|
2118
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
2119
|
+
asset: z.ZodString;
|
|
2120
|
+
equity: z.ZodString;
|
|
2121
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2122
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
2123
|
+
}, z.core.$strip>>;
|
|
2124
|
+
timestamp: z.ZodNumber;
|
|
2125
|
+
accountMode: z.ZodLiteral<"okx:multiCurrencyMargin">;
|
|
2126
|
+
}, z.core.$strip>;
|
|
2127
|
+
type OkxMultiCurrencyMarginBalance = z.infer<typeof OkxMultiCurrencyMarginBalance>;
|
|
2128
|
+
declare const OkxPortfolioMarginBalance: z.ZodObject<{
|
|
2129
|
+
totalEquity: z.ZodNullable<z.ZodString>;
|
|
2130
|
+
withdrawableBalance: z.ZodNullable<z.ZodString>;
|
|
2131
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2132
|
+
poolsShared: z.ZodBoolean;
|
|
2133
|
+
perCollateral: z.ZodArray<z.ZodObject<{
|
|
2134
|
+
asset: z.ZodString;
|
|
2135
|
+
equity: z.ZodString;
|
|
2136
|
+
availableMargin: z.ZodNullable<z.ZodString>;
|
|
2137
|
+
withdrawable: z.ZodNullable<z.ZodString>;
|
|
2138
|
+
}, z.core.$strip>>;
|
|
2139
|
+
timestamp: z.ZodNumber;
|
|
2140
|
+
accountMode: z.ZodLiteral<"okx:portfolioMargin">;
|
|
2141
|
+
}, z.core.$strip>;
|
|
2142
|
+
type OkxPortfolioMarginBalance = z.infer<typeof OkxPortfolioMarginBalance>;
|
|
2143
|
+
|
|
1168
2144
|
type OkxAccountTrackerConfig = AccountTrackerConfig & {
|
|
1169
2145
|
credentials: SupportedCredentials;
|
|
1170
2146
|
};
|
|
@@ -1175,10 +2151,26 @@ declare class OkxAccountTracker extends BaseAccountTracker {
|
|
|
1175
2151
|
private openListenerId;
|
|
1176
2152
|
private rawCoins;
|
|
1177
2153
|
private lastBalance;
|
|
1178
|
-
private
|
|
2154
|
+
private accountMode;
|
|
2155
|
+
private withdrawable;
|
|
2156
|
+
private lastWithdrawableReadAt;
|
|
2157
|
+
private withdrawableRefreshTimer;
|
|
2158
|
+
private withdrawableReadInFlight;
|
|
2159
|
+
private withdrawableReadPending;
|
|
2160
|
+
private lifecycleVersion;
|
|
1179
2161
|
private trackedAssetInfos;
|
|
1180
2162
|
constructor(config: OkxAccountTrackerConfig);
|
|
1181
2163
|
snapshot(): Promise<AccountSnapshot>;
|
|
2164
|
+
/**
|
|
2165
|
+
* OKX sizes no basket in v1: the SDK reads no per-asset max leverage from it, and sizing off
|
|
2166
|
+
* `availableMargin` alone would ship a number no venue field backs. The missing input is
|
|
2167
|
+
* `GET /api/v5/public/position-tiers` → `maxLever`/`imr` per tier, which the client does not
|
|
2168
|
+
* call — and it is NOT `GET /api/v5/account/position-tiers`, a different endpoint carrying no
|
|
2169
|
+
* margin or leverage data at all.
|
|
2170
|
+
*/
|
|
2171
|
+
maxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
2172
|
+
/** The REST path answers the same way — there is no size either way, not a slower one. */
|
|
2173
|
+
snapshotMaxBasketSize(_input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1182
2174
|
/**
|
|
1183
2175
|
* Stateless one-shot per-asset leverage read via `leverage-info`, which accepts up to 20 instIds
|
|
1184
2176
|
* per request (chunked in the client), so N assets cost ceil(N/20) calls. Cross margin only,
|
|
@@ -1189,19 +2181,75 @@ declare class OkxAccountTracker extends BaseAccountTracker {
|
|
|
1189
2181
|
protected cleanupConnections(): Promise<void>;
|
|
1190
2182
|
get isConnected(): boolean;
|
|
1191
2183
|
private fetchSnapshotData;
|
|
2184
|
+
/**
|
|
2185
|
+
* Read how much can leave the trading account, per currency, across everything it owns.
|
|
2186
|
+
*
|
|
2187
|
+
* Best-effort on purpose: this is a fourth signed call that a read-only key may be refused, and
|
|
2188
|
+
* a refusal must cost the caller a `null` field rather than the whole balance.
|
|
2189
|
+
*
|
|
2190
|
+
* A refusal is reported as `failed` rather than as an empty row set, because only the caller
|
|
2191
|
+
* knows what to do with it: the snapshot path has no earlier figure and reports nothing known,
|
|
2192
|
+
* while the live path keeps the figure its last successful read published.
|
|
2193
|
+
*/
|
|
2194
|
+
private readMaxWithdrawals;
|
|
1192
2195
|
protected ensureAssetTracked(instId: string): void;
|
|
1193
2196
|
protected releaseAsset(instId: string): void;
|
|
1194
2197
|
private subscribe;
|
|
1195
2198
|
private handleInitialData;
|
|
1196
2199
|
private routeRaw;
|
|
1197
2200
|
private handleMessage;
|
|
2201
|
+
/**
|
|
2202
|
+
* Fold one account push into the whole account, then publish what that whole account says.
|
|
2203
|
+
*
|
|
2204
|
+
* OKX pushes only what moved: an update names the currencies whose figures changed and leaves
|
|
2205
|
+
* every other currency out. So the rows are taken from the per-currency merge rather than from
|
|
2206
|
+
* the push, and everything read off them — the pool count above all — sees every currency the
|
|
2207
|
+
* account holds. A push naming one of two funded currencies would otherwise read as a
|
|
2208
|
+
* single-pool account and publish scalars that describe neither pool.
|
|
2209
|
+
*
|
|
2210
|
+
* The account-level figures inherit on `??`, never on `||`, because ABSENT and BLANK say
|
|
2211
|
+
* opposite things here. A field this push left out was not restated and its previous value still
|
|
2212
|
+
* stands; a field present as `''` is OKX withdrawing the figure, which it does per account mode —
|
|
2213
|
+
* `availableMarginOf` records the mode that blanks `availEq`. Inheriting a blank would republish
|
|
2214
|
+
* a number the venue no longer states, and it would do it BEHIND `decimalOrNull`, whose whole job
|
|
2215
|
+
* is to publish a blank as `null`: overwriting the blank here means that guard never sees it.
|
|
2216
|
+
*/
|
|
1198
2217
|
private handleBalanceUpdate;
|
|
2218
|
+
/** Publish the balance built from the newest account payload and the cached transferable amounts. */
|
|
2219
|
+
private emitBalance;
|
|
2220
|
+
/**
|
|
2221
|
+
* Queue the next transferable-amount read, no sooner than the venue's own rate limit allows.
|
|
2222
|
+
*
|
|
2223
|
+
* Nothing waits on it: the account update is already published from the cached figure. One
|
|
2224
|
+
* queued read covers every account tick that lands before it runs, which is what stops a burst
|
|
2225
|
+
* of ticks becoming a burst of signed calls — and because a tick always leaves a read queued or
|
|
2226
|
+
* marked pending, a moved figure is still picked up within one interval rather than dropped.
|
|
2227
|
+
*/
|
|
2228
|
+
private refreshWithdrawableSoon;
|
|
2229
|
+
/**
|
|
2230
|
+
* Hold one transferable-amount read open at a time, and queue the ticks that arrive during it.
|
|
2231
|
+
*
|
|
2232
|
+
* Serialising the reads is what keeps the published figure the newest one: two overlapping reads
|
|
2233
|
+
* can come back in either order, and the older answer landing last would publish an amount the
|
|
2234
|
+
* venue has already moved past.
|
|
2235
|
+
*/
|
|
2236
|
+
private refreshWithdrawableBalance;
|
|
2237
|
+
/**
|
|
2238
|
+
* Re-read the transferable amount behind the live path, then re-publish only if it moved.
|
|
2239
|
+
*
|
|
2240
|
+
* Fire-and-forget: the account update is already published with the previous figure, so a slow
|
|
2241
|
+
* read delays the correction instead of blocking the balance. A read that FAILS changes nothing
|
|
2242
|
+
* at all — the last good figure stays published, because a refusal says OKX did not answer, not
|
|
2243
|
+
* that the account has nothing to transfer. The re-publish reads the newest account payload
|
|
2244
|
+
* rather than the one this read started from, so an account update that landed meanwhile is not
|
|
2245
|
+
* rolled back.
|
|
2246
|
+
*/
|
|
2247
|
+
private performWithdrawableRefresh;
|
|
1199
2248
|
}
|
|
1200
2249
|
|
|
1201
2250
|
type CreateAccountTrackerConfig = AccountTrackerConfig & {
|
|
1202
2251
|
account: TradeAccount;
|
|
1203
2252
|
credentials: SupportedCredentials;
|
|
1204
|
-
sdk?: PearSDK;
|
|
1205
2253
|
};
|
|
1206
2254
|
declare function createAccountTracker(exchange: Connector, config: CreateAccountTrackerConfig): AccountTracker;
|
|
1207
2255
|
|
|
@@ -1218,6 +2266,11 @@ declare class ExchangesSDK {
|
|
|
1218
2266
|
status(connection: ExchangeConnection, options?: ConnectOptions): Promise<AccountStatus>;
|
|
1219
2267
|
createTracker(connection: ExchangeConnection): AccountTracker;
|
|
1220
2268
|
snapshot(tradeAccountId: string): Promise<AccountSnapshot>;
|
|
2269
|
+
/**
|
|
2270
|
+
* Sizes a basket in one shot. Routed to the tracker's REST path on purpose: this entry point
|
|
2271
|
+
* builds a throwaway tracker per call, so it must open no socket.
|
|
2272
|
+
*/
|
|
2273
|
+
maxBasketSize(tradeAccountId: string, input: MaxBasketSizeInput): Promise<MaxBasketSizeResult>;
|
|
1221
2274
|
snapshotAssets(tradeAccountId: string, coins: string[]): Promise<AssetSnapshotMap>;
|
|
1222
2275
|
createHelper<E extends ExchangeHelperExchange>(exchange: E): ExchangeHelperMap[E];
|
|
1223
2276
|
createSyncer(connection: ExchangeConnection): AccountSyncer;
|
|
@@ -1225,4 +2278,4 @@ declare class ExchangesSDK {
|
|
|
1225
2278
|
private fetchCredentials;
|
|
1226
2279
|
}
|
|
1227
2280
|
|
|
1228
|
-
export {
|
|
2281
|
+
export { ACCOUNT_MODE_LABELS, ASSET_DECIMALS, AccountBalance, AccountBalanceCore, type AccountHealthStatus, AccountMode, type AccountPosition, type AccountSnapshot, type AccountStatus, type AccountSyncer, type AccountSyncerConfig, type AccountTracker, type AccountTrackerConfig, type AccountWarningReason, type ApiKey, type ApproveIntegratorParams, type ApproveIntegratorResult, AssetId, type AssetSnapshotMap, type BalanceCallback, BaseAccountSyncer, BaseAccountTracker, BaseWs, BasketLeg, BinanceAccountSyncer, BinanceAccountTracker, type BinanceAccountTrackerConfig, BinanceExchangeWs, BinanceMultiAssetBalance, BinanceSingleAssetBalance, BinanceUserDataWs, type BinanceUserDataWsConfig, BinanceWsApi, type BinanceWsApiConfig, BybitAccountSyncer, BybitAccountTracker, type BybitAccountTrackerConfig, BybitExchangeWs, BybitIsolatedMarginBalance, BybitPortfolioMarginBalance, BybitRegularMarginBalance, BybitWs, type BybitWsConfig, type CappedBasketLeg, type CctpDepositHistorySettlement, type CctpDepositIntentParams, type CctpDepositIntentResult, type CctpDepositParams, type CctpDepositProgress, type CctpDepositRegistrationSettlement, type CctpDepositResult, type CctpDepositSettlement, type CctpDepositWalletAdapter, type CheckApiWalletParams, CollateralBalance, type ConnectOptions, type ConnectWalletParams, type ConnectWalletResult, type CreateAccountTrackerConfig, type CreateExchangeWsConfig, DecimalString, type DepositParams, type DepositResult, type ExchangeConnection, type ExchangeHelperExchange, type ExchangeHelperMap, type ExchangeState, ExchangeWs, type ExchangeWsByConnector, ExchangesSDK, type ExchangesSDKConfig, type FastWithdrawParams, type FastWithdrawResult, type FillSyncOutcome, type FundingSyncOutcome, HyperliquidAccountSyncer, HyperliquidAccountTracker, type HyperliquidAccountTrackerConfig, HyperliquidDexState, HyperliquidExchangeWs, type HyperliquidHelper, HyperliquidPortfolioMarginBalance, HyperliquidPortfolioMarginCollateral, HyperliquidStandardBalance, HyperliquidUnifiedBalance, HyperliquidWs, type IntegratorApprovalRequirements, L2_ASSET_DECIMALS, LIGHTER_CCTP_USDC_ADDRESSES, LIGHTER_CCTP_USDC_DECIMALS, LighterAccountSyncer, LighterAccountTracker, type LighterAccountTrackerConfig, LighterClassicBalance, type LighterDeposit, type LighterDepositNetwork, LighterExchangeWs, type LighterHelper, type LighterLookupResult, type LighterOnboardingStatus, LighterUnifiedBalance, LighterWs, type ListExternalFillsParams, type ListExternalFundingParams, type ListExternalPositionsParams, MAX_API_KEY_INDEX, MIN_LIGHTER_CCTP_DEPOSIT_USDC, MIN_LIGHTER_FAST_WITHDRAW_USDC, MIN_USER_API_KEY_INDEX, MarginMode, type MaxBasketSizeCalculation, MaxBasketSizeInput, MaxBasketSizeResult, type MessageListener, OkxAccountSyncer, OkxAccountTracker, type OkxAccountTrackerConfig, OkxExchangeWs, OkxFuturesBalance, OkxMultiCurrencyMarginBalance, OkxPortfolioMarginBalance, OkxSpotBalance, OkxWs, type OkxWsConfig, type OpenListener, type PositionsCallback, RouteType, Side, SignedDecimalString, type StateUpdate, type SupportedCredentials, type TrackedAssetCallback, type TrackedAssetInfo, type WalletClientWithAccount, type WithdrawParams, type WithdrawResult, type WsMessage, computeMaxBasketSize, createAccountSyncer, createAccountTracker, createExchangeWs, createHyperliquidHelper, createLighterHelper, findAvailableApiKeyIndex, getAssetDecimals, getLighterCctpUsdcAddress, usdcAbi };
|