@lynx-crypto/kraken-api 1.0.0 → 1.1.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/dist/index.d.ts CHANGED
@@ -70,6 +70,110 @@ interface KrakenLogger {
70
70
  }
71
71
  type KrakenWsTriggerReference = 'index' | 'last';
72
72
  type KrakenWsPriceType = 'static' | 'pct' | 'quote';
73
+ type KrakenBulkDataset = 'trades' | 'ohlcvt';
74
+ type KrakenBulkQuarter = `${number}Q${1 | 2 | 3 | 4}`;
75
+ type KrakenBulkSource = {
76
+ type: 'complete';
77
+ } | {
78
+ type: 'quarterly';
79
+ quarter: KrakenBulkQuarter;
80
+ };
81
+ interface KrakenBulkClientOptions {
82
+ /**
83
+ * Storage root for bulk data.
84
+ * Default: ~/.lynx-crypto/bulk
85
+ *
86
+ * If relative, resolved against process.cwd().
87
+ */
88
+ storageDir?: string;
89
+ userAgent?: string;
90
+ logger?: KrakenLogger;
91
+ /**
92
+ * Optional Google Drive API key.
93
+ * If omitted, bulk ZIP downloads require manual placement (no Drive downloading, no scraping).
94
+ */
95
+ googleDriveApiKey?: string;
96
+ }
97
+ interface KrakenBulkDownloadResult {
98
+ dataset: KrakenBulkDataset;
99
+ source: KrakenBulkSource;
100
+ zipPath: string;
101
+ bytes: number;
102
+ downloaded: boolean;
103
+ directUrl?: string;
104
+ }
105
+ interface KrakenBulkExtractResult {
106
+ dataset: KrakenBulkDataset;
107
+ source: KrakenBulkSource;
108
+ extractedDir: string;
109
+ filesExtracted: number;
110
+ extracted: boolean;
111
+ }
112
+ type KrakenBulkDeleteScope = 'zips' | 'extracted' | 'all';
113
+ interface KrakenBulkDeleteParams {
114
+ scope: KrakenBulkDeleteScope;
115
+ source?: KrakenBulkSource;
116
+ }
117
+ interface KrakenBulkHasResult {
118
+ zip: boolean;
119
+ extracted: boolean;
120
+ }
121
+ interface KrakenBulkTradeRow {
122
+ ts: number;
123
+ price: string;
124
+ volume: string;
125
+ }
126
+ type KrakenBulkOhlcInterval = 1 | 5 | 15 | 30 | 60 | 240 | 720 | 1440;
127
+ interface KrakenBulkOhlcvtRow {
128
+ ts: number;
129
+ open: string;
130
+ high: string;
131
+ low: string;
132
+ close: string;
133
+ volume: string;
134
+ trades: number;
135
+ }
136
+ interface KrakenBulkTradesQuery {
137
+ pair: string;
138
+ startTs?: number;
139
+ endTs?: number;
140
+ source?: KrakenBulkSource;
141
+ }
142
+ interface KrakenBulkOhlcvtQuery {
143
+ pair: string;
144
+ interval: KrakenBulkOhlcInterval;
145
+ startTs?: number;
146
+ endTs?: number;
147
+ source?: KrakenBulkSource;
148
+ }
149
+ interface KrakenBulkQueryOptions {
150
+ limit?: number;
151
+ }
152
+ type KrakenBulkDownloadProgress = {
153
+ downloadedBytes: number;
154
+ totalBytes?: number;
155
+ };
156
+ type KrakenBulkDownloadProgressCallback = (p: {
157
+ downloadedBytes: number;
158
+ totalBytes?: number;
159
+ }) => void;
160
+ interface KrakenBulkDownloadOptions {
161
+ onProgress?: KrakenBulkDownloadProgressCallback;
162
+ /**
163
+ * If true, re-download even if the ZIP already exists locally.
164
+ * Requires googleDriveApiKey (or env LYNX_CRYPTO_KRAKEN_API_GOOGLE_DRIVE_API_KEY).
165
+ */
166
+ forceRefresh?: boolean;
167
+ }
168
+ type KrakenBulkExtractProgressCallback = (p: {
169
+ extractedFiles: number;
170
+ totalFiles?: number;
171
+ currentFile?: string;
172
+ }) => void;
173
+ type KrakenBulkExtractOptions = {
174
+ onProgress?: KrakenBulkExtractProgressCallback;
175
+ concurrency?: number;
176
+ };
73
177
 
74
178
  /**
75
179
  * Low-level REST base for Kraken clients.
@@ -7860,4 +7964,232 @@ declare class KrakenSpotWebsocketV2Client {
7860
7964
  constructor(options?: KrakenSpotWebsocketClientOptions);
7861
7965
  }
7862
7966
 
7863
- export { type KrakenAccountBalanceMap, type KrakenAccountTransferParams, type KrakenAccountTransferResult, type KrakenAddOrderBatchOrderDescription, type KrakenAddOrderBatchOrderParams, type KrakenAddOrderBatchOrderResult, type KrakenAddOrderBatchParams, type KrakenAddOrderBatchResult, type KrakenAddOrderDescription, type KrakenAddOrderParams, type KrakenAddOrderResult, type KrakenAddOrderStpType, type KrakenAddOrderTimeInForce, type KrakenAmendOrderParams, type KrakenAmendOrderResult, type KrakenApiResponse, type KrakenAssetClass, type KrakenAssetInfo, type KrakenAssetInfoMap, type KrakenAssetPair, type KrakenAssetPairInfoType, type KrakenAssetPairMap, type KrakenAssetPairStatus, type KrakenAssetStatus, type KrakenAssetTickerInfo, type KrakenCancelAllOrdersAfterParams, type KrakenCancelAllOrdersAfterResult, type KrakenCancelAllOrdersResult, type KrakenCancelOrderBatchOrderRef, type KrakenCancelOrderBatchParams, type KrakenCancelOrderBatchResult, type KrakenCancelOrderParams, type KrakenCancelOrderResult, type KrakenClientOptions, type KrakenClosedOrder, type KrakenClosedOrdersCloseTime, type KrakenClosedOrdersMap, type KrakenClosedOrdersResult, type KrakenCreateSubaccountParams, type KrakenCreateSubaccountResult, type KrakenCreditLinesAssetEntry, type KrakenCreditLinesAssetMap, type KrakenCreditLinesLimitsMonitor, type KrakenCreditLinesResponse, type KrakenCreditLinesResult, type KrakenDeleteExportReportParams, type KrakenDeleteExportReportResult, type KrakenDeleteExportReportType, type KrakenDepositAddress, type KrakenDepositMethod, type KrakenDepositStatusEntry, type KrakenEarnAllocateFundsParams, type KrakenEarnAllocateFundsResult, type KrakenEarnAllocationItem, type KrakenEarnAllocationStatus, type KrakenEarnAmountBreakdown, type KrakenEarnDeallocateFundsParams, type KrakenEarnDeallocateFundsResult, type KrakenEarnDeallocationStatus, type KrakenEarnGetAllocationStatusParams, type KrakenEarnGetAllocationStatusResult, type KrakenEarnGetDeallocationStatusParams, type KrakenEarnGetDeallocationStatusResult, type KrakenEarnListAllocationsParams, type KrakenEarnListAllocationsResult, type KrakenEarnListAllocationsResultObject, type KrakenEarnListStrategiesParams, type KrakenEarnListStrategiesResult, type KrakenEarnListStrategiesResultObject, type KrakenEarnLockType, type KrakenEarnStrategy, type KrakenEditOrderDescription, type KrakenEditOrderParams, type KrakenEditOrderResult, type KrakenExportReportFormat, type KrakenExportReportStatus, type KrakenExportReportStatusState, type KrakenExportReportType, type KrakenExtendedBalanceEntry, type KrakenExtendedBalanceMap, type KrakenFeeScheduleEntry, type KrakenFeeTierInfo, type KrakenGetAccountBalanceParams, type KrakenGetAssetInfoParams, type KrakenGetClosedOrdersParams, type KrakenGetCreditLinesParams, type KrakenGetDepositAddressesParams, type KrakenGetDepositAddressesResult, type KrakenGetDepositMethodsParams, type KrakenGetDepositMethodsResult, type KrakenGetDepositStatusParams, type KrakenGetExportReportStatusParams, type KrakenGetExtendedBalanceParams, type KrakenGetLedgersInfoParams, type KrakenGetLedgersQueryParams, type KrakenGetOhlcDataParams, type KrakenGetOpenOrdersParams, type KrakenGetOpenPositionsParams, type KrakenGetOrderAmendsParams, type KrakenGetOrderBookParams, type KrakenGetOrdersInfoParams, type KrakenGetPostTradeDataParams, type KrakenGetPostTradeDataResult, type KrakenGetPreTradeDataParams, type KrakenGetRecentSpreadsParams, type KrakenGetRecentTradesParams, type KrakenGetTickerInformationParams, type KrakenGetTradableAssetPairsParams, type KrakenGetTradeBalanceParams, type KrakenGetTradeVolumeParams, type KrakenGetTradesHistoryParams, type KrakenGetTradesInfoParams, type KrakenGetWebSocketsTokenResult, type KrakenGetWithdrawAddressesParams, type KrakenGetWithdrawAddressesResult, type KrakenGetWithdrawInfoParams, type KrakenGetWithdrawInfoResult, type KrakenGetWithdrawMethodsParams, type KrakenGetWithdrawMethodsResult, type KrakenGetWithdrawStatusParams, type KrakenGetWithdrawStatusResult, type KrakenLedgerEntry, type KrakenLedgerEntryType, type KrakenLedgerMap, type KrakenLedgerTypeFilter, type KrakenLedgersInfoResult, type KrakenLogger, type KrakenOhlcEntry, type KrakenOhlcInterval, type KrakenOhlcMap, type KrakenOhlcResponse, type KrakenOpenOrder, type KrakenOpenOrderDescription, type KrakenOpenOrdersMap, type KrakenOpenOrdersResult, type KrakenOpenPosition, type KrakenOpenPositionsConsolidationMode, type KrakenOpenPositionsMap, type KrakenOrderAmendEntry, type KrakenOrderAmendType, type KrakenOrderAmendsResult, type KrakenOrderBook, type KrakenOrderBookLevel, type KrakenOrderBookMap, type KrakenOrderSide, type KrakenOrderStatus, type KrakenOrderTrigger, type KrakenOrderType, type KrakenPositionStatus, type KrakenPostTradeEntry, type KrakenPreTradeDataResult, type KrakenQueriedLedgersMap, type KrakenQueriedOrder, type KrakenQueriedOrdersMap, type KrakenQueriedTradesMap, type KrakenRebaseMultiplier$1 as KrakenRebaseMultiplier, type KrakenRecentSpreadsResponse, type KrakenRecentTradesResponse, type KrakenRequestExportReportParams, type KrakenRequestExportReportResult, type KrakenRetrieveExportParams, type KrakenRetrieveExportResult, type KrakenServerTime, KrakenSpotAccountDataApi, KrakenSpotEarnApi, KrakenSpotFundingApi, KrakenSpotMarketDataApi, KrakenSpotRestClient, KrakenSpotSubaccountsApi, KrakenSpotTradingApi, KrakenSpotTransparencyApi, type KrakenSpotWebsocketClientOptions, KrakenSpotWebsocketV2Client, KrakenSpotWsAdminApi, KrakenSpotWsMarketDataApi, KrakenSpotWsUserDataApi, KrakenSpotWsUserTradingApi, type KrakenSpreadEntry, type KrakenSpreadsMap, type KrakenSystemStatus, type KrakenSystemStatusResult, type KrakenTickerAssetClass, type KrakenTickerInfoMap, type KrakenTradeBalanceResult, type KrakenTradeEntry, type KrakenTradeHistoryEntry, type KrakenTradeHistoryMap, type KrakenTradeHistoryTypeFilter, type KrakenTradeVolumeFeesMap, type KrakenTradeVolumeResult, type KrakenTradesHistoryResult, type KrakenTradesMap, type KrakenWalletTransferParams, type KrakenWalletTransferResult, type KrakenWebSocketLike, type KrakenWebSocketLikeCtor, KrakenWebsocketBase, type KrakenWebsocketConnectionOptions, type KrakenWebsocketLogger, type KrakenWithdrawAddress, type KrakenWithdrawCancelParams, type KrakenWithdrawCancelResult, type KrakenWithdrawFundsParams, type KrakenWithdrawFundsResult, type KrakenWithdrawInfo, type KrakenWithdrawMethod, type KrakenWithdrawStatusEntry, type KrakenWsAddOrderConditional, type KrakenWsAddOrderOptions, type KrakenWsAddOrderParams, type KrakenWsAddOrderResponse, type KrakenWsAddOrderResult, type KrakenWsAddOrderTriggers, type KrakenWsAmendOrderOptions, type KrakenWsAmendOrderParams, type KrakenWsAmendOrderResponse, type KrakenWsAmendOrderResult, type KrakenWsBalanceEventCategory, type KrakenWsBalanceEventSubtype, type KrakenWsBalanceEventType, type KrakenWsBalanceLedgerTransaction, type KrakenWsBalanceUpdateWalletId, type KrakenWsBalanceWalletEntry, type KrakenWsBalanceWalletId, type KrakenWsBalanceWalletType, type KrakenWsBalancesMessage, type KrakenWsBalancesSnapshotAsset, type KrakenWsBalancesSnapshotMessage, type KrakenWsBalancesSubscribeOptions, type KrakenWsBalancesSubscribeParams, type KrakenWsBalancesSubscribeResponse, type KrakenWsBalancesSubscribeResult, type KrakenWsBalancesUnsubscribeOptions, type KrakenWsBalancesUnsubscribeParams, type KrakenWsBalancesUnsubscribeResponse, type KrakenWsBalancesUnsubscribeResult, type KrakenWsBalancesUpdateMessage, type KrakenWsBatchAddOptions, type KrakenWsBatchAddOrderEntry, type KrakenWsBatchAddOrderResultEntry, type KrakenWsBatchAddParams, type KrakenWsBatchAddResponse, type KrakenWsBatchCancelOptions, type KrakenWsBatchCancelParams, type KrakenWsBatchCancelResponse, type KrakenWsBatchCancelResult, type KrakenWsBookLevel, type KrakenWsBookMessage, type KrakenWsBookSnapshotMessage, type KrakenWsBookSubscribeOptions, type KrakenWsBookSubscribeParams, type KrakenWsBookSubscribeResponse, type KrakenWsBookUnsubscribeOptions, type KrakenWsBookUnsubscribeParams, type KrakenWsBookUnsubscribeResponse, type KrakenWsBookUpdateMessage, type KrakenWsCancelAllOptions, type KrakenWsCancelAllOrdersAfterOptions, type KrakenWsCancelAllOrdersAfterParams, type KrakenWsCancelAllOrdersAfterResponse, type KrakenWsCancelAllOrdersAfterResult, type KrakenWsCancelAllParams, type KrakenWsCancelAllResponse, type KrakenWsCancelAllResult, type KrakenWsCancelOrderOptions, type KrakenWsCancelOrderParams, type KrakenWsCancelOrderResponse, type KrakenWsCancelOrderResult, type KrakenWsEditOrderOptions, type KrakenWsEditOrderParams, type KrakenWsEditOrderResponse, type KrakenWsEditOrderResult, type KrakenWsExecutionContingent, type KrakenWsExecutionFeeEntry, type KrakenWsExecutionReport, type KrakenWsExecutionTimeInForce, type KrakenWsExecutionTriggers, type KrakenWsExecutionType, type KrakenWsExecutionsMessage, type KrakenWsExecutionsSubscribeOptions, type KrakenWsExecutionsSubscribeParams, type KrakenWsExecutionsSubscribeResponse, type KrakenWsExecutionsSubscribeResult, type KrakenWsExecutionsUnsubscribeOptions, type KrakenWsExecutionsUnsubscribeParams, type KrakenWsExecutionsUnsubscribeResponse, type KrakenWsExecutionsUnsubscribeResult, type KrakenWsFeePreference, type KrakenWsHeartbeatHandler, type KrakenWsHeartbeatMessage, type KrakenWsInstrumentAsset, type KrakenWsInstrumentAssetStatus, type KrakenWsInstrumentData, type KrakenWsInstrumentMessage, type KrakenWsInstrumentPair, type KrakenWsInstrumentPairStatus, type KrakenWsInstrumentSnapshotMessage, type KrakenWsInstrumentSubscribeOptions, type KrakenWsInstrumentSubscribeParams, type KrakenWsInstrumentSubscribeResponse, type KrakenWsInstrumentUnsubscribeOptions, type KrakenWsInstrumentUnsubscribeParams, type KrakenWsInstrumentUnsubscribeResponse, type KrakenWsInstrumentUpdateMessage, type KrakenWsLevel3Depth, type KrakenWsLevel3Message, type KrakenWsLevel3OrderEventType, type KrakenWsLevel3SnapshotMessage, type KrakenWsLevel3SubscribeOptions, type KrakenWsLevel3SubscribeParams, type KrakenWsLevel3SubscribeResponse, type KrakenWsLevel3UnsubscribeOptions, type KrakenWsLevel3UnsubscribeParams, type KrakenWsLevel3UnsubscribeResponse, type KrakenWsLevel3UpdateMessage, type KrakenWsLiquidityIndicator, type KrakenWsMessageHandler, type KrakenWsMethodResponseEnvelope, type KrakenWsOhlcMessage, type KrakenWsOhlcSnapshotMessage, type KrakenWsOhlcSubscribeOptions, type KrakenWsOhlcSubscribeParams, type KrakenWsOhlcSubscribeResponse, type KrakenWsOhlcUnsubscribeOptions, type KrakenWsOhlcUnsubscribeParams, type KrakenWsOhlcUnsubscribeResponse, type KrakenWsOhlcUpdateMessage, type KrakenWsOrderSide, type KrakenWsOrderStatus, type KrakenWsOrderType, type KrakenWsPingParams, type KrakenWsPingResponse, type KrakenWsPingResult, type KrakenWsPositionStatus, type KrakenWsPriceType, type KrakenWsStatusData, type KrakenWsStatusUpdateMessage, type KrakenWsStpType, type KrakenWsTickerData, type KrakenWsTickerMessage, type KrakenWsTickerSnapshotMessage, type KrakenWsTickerSubscribeOptions, type KrakenWsTickerSubscribeParams, type KrakenWsTickerSubscribeResponse, type KrakenWsTickerUnsubscribeOptions, type KrakenWsTickerUnsubscribeParams, type KrakenWsTickerUnsubscribeResponse, type KrakenWsTickerUpdateMessage, type KrakenWsTimeInForce, type KrakenWsTradeEntry, type KrakenWsTradeMessage, type KrakenWsTradeOrderType, type KrakenWsTradeSide, type KrakenWsTradeSnapshotMessage, type KrakenWsTradeSubscribeOptions, type KrakenWsTradeSubscribeParams, type KrakenWsTradeSubscribeResponse, type KrakenWsTradeUnsubscribeOptions, type KrakenWsTradeUnsubscribeParams, type KrakenWsTradeUnsubscribeResponse, type KrakenWsTradeUpdateMessage, type KrakenWsTriggerReference, type KrakenWsTriggerStatus };
7967
+ declare class KrakenBulkBase {
7968
+ readonly logger?: KrakenLogger;
7969
+ readonly userAgent?: string;
7970
+ private readonly storageDir;
7971
+ private readonly googleDriveApiKey?;
7972
+ private driveFolderCache;
7973
+ constructor(options?: KrakenBulkClientOptions);
7974
+ driveApiKeyEnvVar(): string;
7975
+ hasGoogleDriveApiKey(): boolean;
7976
+ getStorageDir(): string;
7977
+ sourceKey(source: KrakenBulkSource): string;
7978
+ datasetDir(dataset: KrakenBulkDataset): string;
7979
+ zipsDir(dataset: KrakenBulkDataset): string;
7980
+ extractedRootDir(dataset: KrakenBulkDataset): string;
7981
+ private zipBucket;
7982
+ private extractBucket;
7983
+ private zipsBucketDir;
7984
+ private extractedBucketDir;
7985
+ /**
7986
+ * New location ONLY:
7987
+ * - .../zips/complete/complete.zip
7988
+ * - .../zips/quarterly/<YYYYQn>.zip
7989
+ */
7990
+ zipPath(dataset: KrakenBulkDataset, source: KrakenBulkSource): string;
7991
+ /**
7992
+ * New extracted location ONLY:
7993
+ * - .../extracted/complete/
7994
+ * - .../extracted/quarterly/<YYYYQn>/
7995
+ */
7996
+ extractedDir(dataset: KrakenBulkDataset, source: KrakenBulkSource): string;
7997
+ ensureDatasetDirs(dataset: KrakenBulkDataset): Promise<void>;
7998
+ has(dataset: KrakenBulkDataset, source: KrakenBulkSource): Promise<KrakenBulkHasResult>;
7999
+ downloadByFileId(dataset: KrakenBulkDataset, source: KrakenBulkSource, fileId: string, originalUrl: string, opts?: KrakenBulkDownloadOptions): Promise<KrakenBulkDownloadResult>;
8000
+ extract(dataset: KrakenBulkDataset, source: KrakenBulkSource, opts?: KrakenBulkExtractOptions): Promise<KrakenBulkExtractResult>;
8001
+ delete(dataset: KrakenBulkDataset, params: KrakenBulkDeleteParams): Promise<void>;
8002
+ listDriveFolder(folderId: string): Promise<Array<{
8003
+ id: string;
8004
+ name: string;
8005
+ }>>;
8006
+ safeStatSize(p: string): Promise<number>;
8007
+ private markerOkPath;
8008
+ private markerInProgressPath;
8009
+ private writeMarkerInProgress;
8010
+ private writeMarkerOk;
8011
+ private isExtractedReady;
8012
+ private dirHasCsv;
8013
+ }
8014
+
8015
+ /**
8016
+ * Kraken Bulk OHLCVT API
8017
+ * Provides methods to download, extract, check, delete, and query OHLCVT bulk data.
8018
+ *
8019
+ * Supports complete and quarterly datasets.
8020
+ * Requires Google Drive API key for downloading quarterly datasets.
8021
+ */
8022
+ declare class KrakenBulkOhlcvtApi {
8023
+ private readonly base;
8024
+ constructor(base: KrakenBulkBase);
8025
+ /**
8026
+ * Download OHLCVT bulk data ZIP.
8027
+ *
8028
+ * @param source
8029
+ * @param opts
8030
+ * @returns { Promise<KrakenBulkDownloadResult> }
8031
+ */
8032
+ download(source: KrakenBulkSource, opts?: KrakenBulkDownloadOptions): Promise<KrakenBulkDownloadResult>;
8033
+ /**
8034
+ * Extract OHLCVT bulk data ZIP.
8035
+ *
8036
+ * @param source
8037
+ * @param opts
8038
+ * @returns { Promise<KrakenBulkExtractResult> }
8039
+ */
8040
+ extract(source: KrakenBulkSource, opts?: KrakenBulkExtractOptions): Promise<KrakenBulkExtractResult>;
8041
+ /**
8042
+ * Check if OHLCVT bulk data ZIP and extracted directory exist.
8043
+ *
8044
+ * @param source
8045
+ * @returns { Promise<KrakenBulkHasResult> }
8046
+ */
8047
+ has(source: KrakenBulkSource): Promise<KrakenBulkHasResult>;
8048
+ /**
8049
+ * Delete OHLCVT bulk data ZIP and/or extracted directory.
8050
+ *
8051
+ * @param params
8052
+ * @returns { Promise<void> }
8053
+ */
8054
+ delete(params: {
8055
+ scope: 'zips' | 'extracted' | 'all';
8056
+ source?: KrakenBulkSource;
8057
+ }): Promise<void>;
8058
+ /**
8059
+ * Query OHLCVT data for a specific pair and interval.
8060
+ *
8061
+ * @param q
8062
+ * @param opts
8063
+ * @returns { AsyncIterable<KrakenBulkOhlcvtRow> }
8064
+ */
8065
+ query(q: KrakenBulkOhlcvtQuery, opts?: KrakenBulkQueryOptions): AsyncIterable<KrakenBulkOhlcvtRow>;
8066
+ /**
8067
+ * List available trading pairs in the extracted OHLCVT data.
8068
+ *
8069
+ * @param source
8070
+ * @returns { Promise<string[]> }
8071
+ */
8072
+ listPairs(source?: KrakenBulkSource): Promise<string[]>;
8073
+ /**
8074
+ * List available intervals for a specific trading pair in the extracted OHLCVT data.
8075
+ *
8076
+ * @param pair
8077
+ * @param source
8078
+ * @returns { Promise<KrakenBulkOhlcInterval[]> }
8079
+ */
8080
+ listIntervals(pair: string, source?: KrakenBulkSource): Promise<KrakenBulkOhlcInterval[]>;
8081
+ /**
8082
+ * List available quarters for OHLCVT quarterly datasets.
8083
+ *
8084
+ * @returns { Promise<string[]> }
8085
+ */
8086
+ listAvailableQuarters(): Promise<string[]>;
8087
+ /**
8088
+ * Query from extracted data.
8089
+ *
8090
+ * @param source
8091
+ * @param q
8092
+ * @param opts
8093
+ * @returns { AsyncIterable<KrakenBulkOhlcvtRow> }
8094
+ */
8095
+ private queryFromExtracted;
8096
+ /**
8097
+ * Download quarterly OHLCVT ZIP.
8098
+ *
8099
+ * @param quarter
8100
+ * @param opts
8101
+ * @returns { Promise<KrakenBulkDownloadResult> }
8102
+ */
8103
+ private downloadQuarter;
8104
+ }
8105
+
8106
+ /**
8107
+ * Kraken Bulk Trades API
8108
+ * Provides methods to download, extract, check, delete, and query trades bulk data.
8109
+ *
8110
+ * Supports complete and quarterly datasets.
8111
+ * Requires Google Drive API key for downloading quarterly datasets.
8112
+ */
8113
+ declare class KrakenBulkTradesApi {
8114
+ private readonly base;
8115
+ constructor(base: KrakenBulkBase);
8116
+ /**
8117
+ * Download Trades bulk data ZIP.
8118
+ *
8119
+ * @param source
8120
+ * @param opts
8121
+ * @returns { Promise<KrakenBulkDownloadResult> }
8122
+ */
8123
+ download(source: KrakenBulkSource, opts?: KrakenBulkDownloadOptions): Promise<KrakenBulkDownloadResult>;
8124
+ /**
8125
+ * Extract Trades bulk data ZIP.
8126
+ *
8127
+ * @param source
8128
+ * @param opts
8129
+ * @returns { Promise<KrakenBulkExtractResult> }
8130
+ */
8131
+ extract(source: KrakenBulkSource, opts?: KrakenBulkExtractOptions): Promise<KrakenBulkExtractResult>;
8132
+ /**
8133
+ * Check if Trades bulk data ZIP and extracted directory exist.
8134
+ *
8135
+ * @param source
8136
+ * @returns { Promise<KrakenBulkHasResult> }
8137
+ */
8138
+ has(source: KrakenBulkSource): Promise<KrakenBulkHasResult>;
8139
+ /**
8140
+ * Delete Trades bulk data ZIP and/or extracted directory.
8141
+ *
8142
+ * @param params
8143
+ * @returns { Promise<void> }
8144
+ */
8145
+ delete(params: {
8146
+ scope: 'zips' | 'extracted' | 'all';
8147
+ source?: KrakenBulkSource;
8148
+ }): Promise<void>;
8149
+ /**
8150
+ * Query Trades data for a specific pair.
8151
+ *
8152
+ * @param q
8153
+ * @param opts
8154
+ * @returns { AsyncIterable<KrakenBulkTradeRow> }
8155
+ */
8156
+ query(q: KrakenBulkTradesQuery, opts?: KrakenBulkQueryOptions): AsyncIterable<KrakenBulkTradeRow>;
8157
+ /**
8158
+ * List available trading pairs in the extracted Trades data.
8159
+ *
8160
+ * @param source
8161
+ * @returns { Promise<string[]> }
8162
+ */
8163
+ listPairs(source?: KrakenBulkSource): Promise<string[]>;
8164
+ /**
8165
+ * List available quarters for Trades quarterly datasets.
8166
+ *
8167
+ * @returns { Promise<string[]> }
8168
+ */
8169
+ listAvailableQuarters(): Promise<string[]>;
8170
+ /**
8171
+ * Query from extracted data.
8172
+ *
8173
+ * Supports both common CSV layouts:
8174
+ * - [ts, price, volume, ...]
8175
+ * - [price, volume, ts, ...] (Kraken REST-style)
8176
+ */
8177
+ private queryFromExtracted;
8178
+ /**
8179
+ * Download quarterly Trades ZIP.
8180
+ *
8181
+ * @param quarter
8182
+ * @param opts
8183
+ * @returns { Promise<KrakenBulkDownloadResult> }
8184
+ */
8185
+ private downloadQuarter;
8186
+ }
8187
+
8188
+ declare class KrakenBulkClient {
8189
+ readonly trades: KrakenBulkTradesApi;
8190
+ readonly ohlcvt: KrakenBulkOhlcvtApi;
8191
+ private readonly base;
8192
+ constructor(options?: KrakenBulkClientOptions);
8193
+ }
8194
+
8195
+ export { type KrakenAccountBalanceMap, type KrakenAccountTransferParams, type KrakenAccountTransferResult, type KrakenAddOrderBatchOrderDescription, type KrakenAddOrderBatchOrderParams, type KrakenAddOrderBatchOrderResult, type KrakenAddOrderBatchParams, type KrakenAddOrderBatchResult, type KrakenAddOrderDescription, type KrakenAddOrderParams, type KrakenAddOrderResult, type KrakenAddOrderStpType, type KrakenAddOrderTimeInForce, type KrakenAmendOrderParams, type KrakenAmendOrderResult, type KrakenApiResponse, type KrakenAssetClass, type KrakenAssetInfo, type KrakenAssetInfoMap, type KrakenAssetPair, type KrakenAssetPairInfoType, type KrakenAssetPairMap, type KrakenAssetPairStatus, type KrakenAssetStatus, type KrakenAssetTickerInfo, KrakenBulkClient, type KrakenBulkClientOptions, type KrakenBulkDataset, type KrakenBulkDeleteParams, type KrakenBulkDeleteScope, type KrakenBulkDownloadOptions, type KrakenBulkDownloadProgress, type KrakenBulkDownloadProgressCallback, type KrakenBulkDownloadResult, type KrakenBulkExtractOptions, type KrakenBulkExtractProgressCallback, type KrakenBulkExtractResult, type KrakenBulkHasResult, type KrakenBulkOhlcInterval, type KrakenBulkOhlcvtQuery, type KrakenBulkOhlcvtRow, type KrakenBulkQuarter, type KrakenBulkQueryOptions, type KrakenBulkSource, type KrakenBulkTradeRow, type KrakenBulkTradesQuery, type KrakenCancelAllOrdersAfterParams, type KrakenCancelAllOrdersAfterResult, type KrakenCancelAllOrdersResult, type KrakenCancelOrderBatchOrderRef, type KrakenCancelOrderBatchParams, type KrakenCancelOrderBatchResult, type KrakenCancelOrderParams, type KrakenCancelOrderResult, type KrakenClientOptions, type KrakenClosedOrder, type KrakenClosedOrdersCloseTime, type KrakenClosedOrdersMap, type KrakenClosedOrdersResult, type KrakenCreateSubaccountParams, type KrakenCreateSubaccountResult, type KrakenCreditLinesAssetEntry, type KrakenCreditLinesAssetMap, type KrakenCreditLinesLimitsMonitor, type KrakenCreditLinesResponse, type KrakenCreditLinesResult, type KrakenDeleteExportReportParams, type KrakenDeleteExportReportResult, type KrakenDeleteExportReportType, type KrakenDepositAddress, type KrakenDepositMethod, type KrakenDepositStatusEntry, type KrakenEarnAllocateFundsParams, type KrakenEarnAllocateFundsResult, type KrakenEarnAllocationItem, type KrakenEarnAllocationStatus, type KrakenEarnAmountBreakdown, type KrakenEarnDeallocateFundsParams, type KrakenEarnDeallocateFundsResult, type KrakenEarnDeallocationStatus, type KrakenEarnGetAllocationStatusParams, type KrakenEarnGetAllocationStatusResult, type KrakenEarnGetDeallocationStatusParams, type KrakenEarnGetDeallocationStatusResult, type KrakenEarnListAllocationsParams, type KrakenEarnListAllocationsResult, type KrakenEarnListAllocationsResultObject, type KrakenEarnListStrategiesParams, type KrakenEarnListStrategiesResult, type KrakenEarnListStrategiesResultObject, type KrakenEarnLockType, type KrakenEarnStrategy, type KrakenEditOrderDescription, type KrakenEditOrderParams, type KrakenEditOrderResult, type KrakenExportReportFormat, type KrakenExportReportStatus, type KrakenExportReportStatusState, type KrakenExportReportType, type KrakenExtendedBalanceEntry, type KrakenExtendedBalanceMap, type KrakenFeeScheduleEntry, type KrakenFeeTierInfo, type KrakenGetAccountBalanceParams, type KrakenGetAssetInfoParams, type KrakenGetClosedOrdersParams, type KrakenGetCreditLinesParams, type KrakenGetDepositAddressesParams, type KrakenGetDepositAddressesResult, type KrakenGetDepositMethodsParams, type KrakenGetDepositMethodsResult, type KrakenGetDepositStatusParams, type KrakenGetExportReportStatusParams, type KrakenGetExtendedBalanceParams, type KrakenGetLedgersInfoParams, type KrakenGetLedgersQueryParams, type KrakenGetOhlcDataParams, type KrakenGetOpenOrdersParams, type KrakenGetOpenPositionsParams, type KrakenGetOrderAmendsParams, type KrakenGetOrderBookParams, type KrakenGetOrdersInfoParams, type KrakenGetPostTradeDataParams, type KrakenGetPostTradeDataResult, type KrakenGetPreTradeDataParams, type KrakenGetRecentSpreadsParams, type KrakenGetRecentTradesParams, type KrakenGetTickerInformationParams, type KrakenGetTradableAssetPairsParams, type KrakenGetTradeBalanceParams, type KrakenGetTradeVolumeParams, type KrakenGetTradesHistoryParams, type KrakenGetTradesInfoParams, type KrakenGetWebSocketsTokenResult, type KrakenGetWithdrawAddressesParams, type KrakenGetWithdrawAddressesResult, type KrakenGetWithdrawInfoParams, type KrakenGetWithdrawInfoResult, type KrakenGetWithdrawMethodsParams, type KrakenGetWithdrawMethodsResult, type KrakenGetWithdrawStatusParams, type KrakenGetWithdrawStatusResult, type KrakenLedgerEntry, type KrakenLedgerEntryType, type KrakenLedgerMap, type KrakenLedgerTypeFilter, type KrakenLedgersInfoResult, type KrakenLogger, type KrakenOhlcEntry, type KrakenOhlcInterval, type KrakenOhlcMap, type KrakenOhlcResponse, type KrakenOpenOrder, type KrakenOpenOrderDescription, type KrakenOpenOrdersMap, type KrakenOpenOrdersResult, type KrakenOpenPosition, type KrakenOpenPositionsConsolidationMode, type KrakenOpenPositionsMap, type KrakenOrderAmendEntry, type KrakenOrderAmendType, type KrakenOrderAmendsResult, type KrakenOrderBook, type KrakenOrderBookLevel, type KrakenOrderBookMap, type KrakenOrderSide, type KrakenOrderStatus, type KrakenOrderTrigger, type KrakenOrderType, type KrakenPositionStatus, type KrakenPostTradeEntry, type KrakenPreTradeDataResult, type KrakenQueriedLedgersMap, type KrakenQueriedOrder, type KrakenQueriedOrdersMap, type KrakenQueriedTradesMap, type KrakenRebaseMultiplier$1 as KrakenRebaseMultiplier, type KrakenRecentSpreadsResponse, type KrakenRecentTradesResponse, type KrakenRequestExportReportParams, type KrakenRequestExportReportResult, type KrakenRetrieveExportParams, type KrakenRetrieveExportResult, type KrakenServerTime, KrakenSpotAccountDataApi, KrakenSpotEarnApi, KrakenSpotFundingApi, KrakenSpotMarketDataApi, KrakenSpotRestClient, KrakenSpotSubaccountsApi, KrakenSpotTradingApi, KrakenSpotTransparencyApi, type KrakenSpotWebsocketClientOptions, KrakenSpotWebsocketV2Client, KrakenSpotWsAdminApi, KrakenSpotWsMarketDataApi, KrakenSpotWsUserDataApi, KrakenSpotWsUserTradingApi, type KrakenSpreadEntry, type KrakenSpreadsMap, type KrakenSystemStatus, type KrakenSystemStatusResult, type KrakenTickerAssetClass, type KrakenTickerInfoMap, type KrakenTradeBalanceResult, type KrakenTradeEntry, type KrakenTradeHistoryEntry, type KrakenTradeHistoryMap, type KrakenTradeHistoryTypeFilter, type KrakenTradeVolumeFeesMap, type KrakenTradeVolumeResult, type KrakenTradesHistoryResult, type KrakenTradesMap, type KrakenWalletTransferParams, type KrakenWalletTransferResult, type KrakenWebSocketLike, type KrakenWebSocketLikeCtor, KrakenWebsocketBase, type KrakenWebsocketConnectionOptions, type KrakenWebsocketLogger, type KrakenWithdrawAddress, type KrakenWithdrawCancelParams, type KrakenWithdrawCancelResult, type KrakenWithdrawFundsParams, type KrakenWithdrawFundsResult, type KrakenWithdrawInfo, type KrakenWithdrawMethod, type KrakenWithdrawStatusEntry, type KrakenWsAddOrderConditional, type KrakenWsAddOrderOptions, type KrakenWsAddOrderParams, type KrakenWsAddOrderResponse, type KrakenWsAddOrderResult, type KrakenWsAddOrderTriggers, type KrakenWsAmendOrderOptions, type KrakenWsAmendOrderParams, type KrakenWsAmendOrderResponse, type KrakenWsAmendOrderResult, type KrakenWsBalanceEventCategory, type KrakenWsBalanceEventSubtype, type KrakenWsBalanceEventType, type KrakenWsBalanceLedgerTransaction, type KrakenWsBalanceUpdateWalletId, type KrakenWsBalanceWalletEntry, type KrakenWsBalanceWalletId, type KrakenWsBalanceWalletType, type KrakenWsBalancesMessage, type KrakenWsBalancesSnapshotAsset, type KrakenWsBalancesSnapshotMessage, type KrakenWsBalancesSubscribeOptions, type KrakenWsBalancesSubscribeParams, type KrakenWsBalancesSubscribeResponse, type KrakenWsBalancesSubscribeResult, type KrakenWsBalancesUnsubscribeOptions, type KrakenWsBalancesUnsubscribeParams, type KrakenWsBalancesUnsubscribeResponse, type KrakenWsBalancesUnsubscribeResult, type KrakenWsBalancesUpdateMessage, type KrakenWsBatchAddOptions, type KrakenWsBatchAddOrderEntry, type KrakenWsBatchAddOrderResultEntry, type KrakenWsBatchAddParams, type KrakenWsBatchAddResponse, type KrakenWsBatchCancelOptions, type KrakenWsBatchCancelParams, type KrakenWsBatchCancelResponse, type KrakenWsBatchCancelResult, type KrakenWsBookLevel, type KrakenWsBookMessage, type KrakenWsBookSnapshotMessage, type KrakenWsBookSubscribeOptions, type KrakenWsBookSubscribeParams, type KrakenWsBookSubscribeResponse, type KrakenWsBookUnsubscribeOptions, type KrakenWsBookUnsubscribeParams, type KrakenWsBookUnsubscribeResponse, type KrakenWsBookUpdateMessage, type KrakenWsCancelAllOptions, type KrakenWsCancelAllOrdersAfterOptions, type KrakenWsCancelAllOrdersAfterParams, type KrakenWsCancelAllOrdersAfterResponse, type KrakenWsCancelAllOrdersAfterResult, type KrakenWsCancelAllParams, type KrakenWsCancelAllResponse, type KrakenWsCancelAllResult, type KrakenWsCancelOrderOptions, type KrakenWsCancelOrderParams, type KrakenWsCancelOrderResponse, type KrakenWsCancelOrderResult, type KrakenWsEditOrderOptions, type KrakenWsEditOrderParams, type KrakenWsEditOrderResponse, type KrakenWsEditOrderResult, type KrakenWsExecutionContingent, type KrakenWsExecutionFeeEntry, type KrakenWsExecutionReport, type KrakenWsExecutionTimeInForce, type KrakenWsExecutionTriggers, type KrakenWsExecutionType, type KrakenWsExecutionsMessage, type KrakenWsExecutionsSubscribeOptions, type KrakenWsExecutionsSubscribeParams, type KrakenWsExecutionsSubscribeResponse, type KrakenWsExecutionsSubscribeResult, type KrakenWsExecutionsUnsubscribeOptions, type KrakenWsExecutionsUnsubscribeParams, type KrakenWsExecutionsUnsubscribeResponse, type KrakenWsExecutionsUnsubscribeResult, type KrakenWsFeePreference, type KrakenWsHeartbeatHandler, type KrakenWsHeartbeatMessage, type KrakenWsInstrumentAsset, type KrakenWsInstrumentAssetStatus, type KrakenWsInstrumentData, type KrakenWsInstrumentMessage, type KrakenWsInstrumentPair, type KrakenWsInstrumentPairStatus, type KrakenWsInstrumentSnapshotMessage, type KrakenWsInstrumentSubscribeOptions, type KrakenWsInstrumentSubscribeParams, type KrakenWsInstrumentSubscribeResponse, type KrakenWsInstrumentUnsubscribeOptions, type KrakenWsInstrumentUnsubscribeParams, type KrakenWsInstrumentUnsubscribeResponse, type KrakenWsInstrumentUpdateMessage, type KrakenWsLevel3Depth, type KrakenWsLevel3Message, type KrakenWsLevel3OrderEventType, type KrakenWsLevel3SnapshotMessage, type KrakenWsLevel3SubscribeOptions, type KrakenWsLevel3SubscribeParams, type KrakenWsLevel3SubscribeResponse, type KrakenWsLevel3UnsubscribeOptions, type KrakenWsLevel3UnsubscribeParams, type KrakenWsLevel3UnsubscribeResponse, type KrakenWsLevel3UpdateMessage, type KrakenWsLiquidityIndicator, type KrakenWsMessageHandler, type KrakenWsMethodResponseEnvelope, type KrakenWsOhlcMessage, type KrakenWsOhlcSnapshotMessage, type KrakenWsOhlcSubscribeOptions, type KrakenWsOhlcSubscribeParams, type KrakenWsOhlcSubscribeResponse, type KrakenWsOhlcUnsubscribeOptions, type KrakenWsOhlcUnsubscribeParams, type KrakenWsOhlcUnsubscribeResponse, type KrakenWsOhlcUpdateMessage, type KrakenWsOrderSide, type KrakenWsOrderStatus, type KrakenWsOrderType, type KrakenWsPingParams, type KrakenWsPingResponse, type KrakenWsPingResult, type KrakenWsPositionStatus, type KrakenWsPriceType, type KrakenWsStatusData, type KrakenWsStatusUpdateMessage, type KrakenWsStpType, type KrakenWsTickerData, type KrakenWsTickerMessage, type KrakenWsTickerSnapshotMessage, type KrakenWsTickerSubscribeOptions, type KrakenWsTickerSubscribeParams, type KrakenWsTickerSubscribeResponse, type KrakenWsTickerUnsubscribeOptions, type KrakenWsTickerUnsubscribeParams, type KrakenWsTickerUnsubscribeResponse, type KrakenWsTickerUpdateMessage, type KrakenWsTimeInForce, type KrakenWsTradeEntry, type KrakenWsTradeMessage, type KrakenWsTradeOrderType, type KrakenWsTradeSide, type KrakenWsTradeSnapshotMessage, type KrakenWsTradeSubscribeOptions, type KrakenWsTradeSubscribeParams, type KrakenWsTradeSubscribeResponse, type KrakenWsTradeUnsubscribeOptions, type KrakenWsTradeUnsubscribeParams, type KrakenWsTradeUnsubscribeResponse, type KrakenWsTradeUpdateMessage, type KrakenWsTriggerReference, type KrakenWsTriggerStatus };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import {createHash,createHmac}from'crypto';import {WebSocket}from'ws';var f=class{constructor(e,r){this.maxCounter=e;this.decayPerSec=r;}counter=0;lastTs=Date.now();queue=[];draining=false;schedule(e,r){let n=Math.max(0,r?.cost??1);return new Promise((s,o)=>{this.queue.push({fn:e,resolve:s,reject:o,cost:n}),this.drain();})}decayNow(){let e=Date.now(),r=(e-this.lastTs)/1e3;r>0&&(this.counter=Math.max(0,this.counter-r*this.decayPerSec),this.lastTs=e);}async drain(){if(!this.draining){this.draining=true;try{for(;this.queue.length>0;){this.decayNow();let e=this.queue[0];if(this.counter+e.cost<=this.maxCounter){this.queue.shift(),this.counter+=e.cost;try{let o=await e.fn();e.resolve(o);}catch(o){e.reject(o);}continue}let n=(this.counter+e.cost-this.maxCounter)/this.decayPerSec,s=Math.max(50,Math.ceil(n*1e3));await w(s);}}finally{this.draining=false;}}}};function I(t){switch(t){case "pro":return {maxCounter:20,decayPerSec:1};case "intermediate":return {maxCounter:20,decayPerSec:.5};case "starter":default:return {maxCounter:15,decayPerSec:.33}}}function L(t){return t.includes("TradesHistory")||t.includes("Ledgers")||t.includes("TradeBalance")?2:1}function v(t){return t.includes("/AddOrder")||t.includes("/CancelOrder")||t.includes("/CancelAll")||t.includes("/EditOrder")||t.includes("/AddOrderBatch")||t.includes("/CancelOrderBatch")}function w(t){return new Promise(e=>setTimeout(e,t))}function D(t){let e=t*.2;return Math.max(0,Math.floor(t+(Math.random()*2-1)*e))}function M(t){let e=t.match(/EService:\s*Throttled:\s*(\d+)/i);if(!e)return null;let r=Number(e[1]);return Number.isFinite(r)?r:null}var b=class extends Error{name="KrakenApiError";endpoint;httpStatus;httpStatusText;krakenErrorCodes;rawBody;constructor(e,r={}){super(e),Object.setPrototypeOf(this,new.target.prototype),this.endpoint=r.endpoint,this.httpStatus=r.httpStatus,this.httpStatusText=r.httpStatusText,this.krakenErrorCodes=r.krakenErrorCodes,this.rawBody=r.rawBody;}};var h=class{baseUrl;timeoutMs;userAgent;apiKey;apiSecret;logger;lastNonce;lastMs=0;restLimiter;tradingLimiter;rateLimitOptions;restCostFn;tradingCostFn;constructor(e={}){this.baseUrl=e.baseUrl??"https://api.kraken.com",this.timeoutMs=e.timeoutMs??1e4,this.userAgent=e.userAgent,this.apiKey=e.apiKey,this.apiSecret=e.apiSecret,this.logger=e.logger;let r=e.rateLimit??{},n=r.mode??"auto",s=r.tier??"starter";if(this.rateLimitOptions={retryOnRateLimit:r.retryOnRateLimit??true,maxRetries:r.maxRetries??5},this.restCostFn=r.restCostFn??L,this.tradingCostFn=r.tradingCostFn??(()=>1),e.limiter?.rest&&(this.restLimiter=e.limiter.rest),e.limiter?.trading&&(this.tradingLimiter=e.limiter.trading),n!=="off"){if(!this.restLimiter){let{maxCounter:o,decayPerSec:a}=I(s);this.restLimiter=new f(o,a);}this.tradingLimiter||(this.tradingLimiter=new f(10,1));}}createNonce(){let e=Date.now();return this.lastNonce===void 0?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e,this.lastNonce.toString()):(e>this.lastMs?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e):this.lastNonce=this.lastNonce+1n,this.lastNonce.toString())}async publicGet(e,r){let n=new URL(e,this.baseUrl);if(r)for(let[s,o]of Object.entries(r))n.searchParams.set(s,String(o));return this.logger?.debug?.("Kraken REST public GET request",{endpoint:e,url:n.toString(),query:r}),this.scheduleWithRetry(e,async()=>{let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs);try{let a=await fetch(n,{method:"GET",signal:s.signal,headers:this.userAgent?{"User-Agent":this.userAgent}:void 0});if(!a.ok)throw this.logger?.error?.("Kraken REST HTTP error",{endpoint:e,status:a.status,statusText:a.statusText}),new b(`HTTP error from Kraken: ${a.status} ${a.statusText}`,{endpoint:e,httpStatus:a.status,httpStatusText:a.statusText});let i;try{i=await a.json();}catch(l){throw this.logger?.error?.("Kraken REST JSON parse error",{endpoint:e,error:l}),new b("Failed to parse Kraken response JSON",{endpoint:e,httpStatus:a.status})}if(i.error?.length)throw this.logger?.warn?.("Kraken REST API error",{endpoint:e,krakenErrors:i.error}),new b(`Kraken API error: ${i.error.join(", ")}`,{endpoint:e,httpStatus:a.status,krakenErrorCodes:i.error,rawBody:i});return this.logger?.debug?.("Kraken REST public GET success",{endpoint:e}),i.result}finally{clearTimeout(o);}})}async privatePost(e,r){if(!this.apiKey||!this.apiSecret)throw new b("Missing apiKey or apiSecret for Kraken private API call",{endpoint:e});let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),o=new URLSearchParams;if(o.set("nonce",s),r)for(let[p,K]of Object.entries(r))K!==void 0&&o.set(p,String(K));let a=o.toString(),i=createHash("sha256").update(s+a).digest(),l=Buffer.from(this.apiSecret,"base64"),d=createHmac("sha512",l);d.update(e),d.update(i);let c=d.digest("base64");this.logger?.debug?.("Kraken REST private POST request",{endpoint:e,url:n.toString(),hasParams:!!r});let k=new AbortController,u=setTimeout(()=>k.abort(),this.timeoutMs);try{let p=await fetch(n,{method:"POST",signal:k.signal,headers:{"Content-Type":"application/x-www-form-urlencoded","API-Key":this.apiKey,"API-Sign":c,...this.userAgent?{"User-Agent":this.userAgent}:{}},body:a});if(!p.ok)throw this.logger?.error?.("Kraken REST private HTTP error",{endpoint:e,status:p.status,statusText:p.statusText}),new b(`HTTP error from Kraken private API: ${p.status} ${p.statusText}`,{endpoint:e,httpStatus:p.status,httpStatusText:p.statusText});let K;try{K=await p.json();}catch(m){throw this.logger?.error?.("Kraken REST private JSON parse error",{endpoint:e,error:m}),new b("Failed to parse Kraken private API response JSON",{endpoint:e,httpStatus:p.status})}if(K.error?.length)throw this.logger?.warn?.("Kraken REST private API error",{endpoint:e,krakenErrors:K.error}),new b(`Kraken private API error: ${K.error.join(", ")}`,{endpoint:e,httpStatus:p.status,krakenErrorCodes:K.error,rawBody:K});return this.logger?.debug?.("Kraken REST private POST success",{endpoint:e}),K.result}finally{clearTimeout(u);}})}async privatePostBinary(e,r){if(!this.apiKey||!this.apiSecret)throw new Error("KrakenRestBase: apiKey and apiSecret are required for private endpoints");let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),a=new URLSearchParams({nonce:s,...r??{}}).toString(),i=this.signPrivateRequest(e,s,a);this.logger?.debug?.("[KrakenRestBase] privatePostBinary request",{url:n.toString(),path:e,body:r});let l={"API-Key":this.apiKey,"API-Sign":i,"User-Agent":this.userAgent??"lynx-crypto-kraken-client/0.1.0","Content-Type":"application/x-www-form-urlencoded"},d=await fetch(n.toString(),{method:"POST",headers:l,body:a});if(!d.ok){let u=await d.text().catch(()=>"");throw this.logger?.error?.("[KrakenRestBase] privatePostBinary HTTP error",{status:d.status,statusText:d.statusText,body:u}),new Error(`Kraken privatePostBinary failed: ${d.status} ${d.statusText} \u2013 ${u}`)}if((d.headers.get("content-type")??"").includes("application/json")){let u=await d.json().catch(()=>null);if(!u)throw new Error("Kraken privatePostBinary: expected JSON body for error response");let p=u.error??[];if(p.length>0){let K=`Kraken API error: ${p.join(", ")}`;this.logger?.error?.("[KrakenRestBase] Kraken API error (binary response)",{errors:p});let m=new Error(K);throw m.krakenErrors=p,m}throw new Error("Kraken privatePostBinary: expected binary data but got JSON without errors")}let k=await d.arrayBuffer();return this.logger?.debug?.("[KrakenRestBase] privatePostBinary success",{bytes:k.byteLength}),k})}signPrivateRequest(e,r,n){if(!this.apiSecret)throw new Error("KrakenRestBase: apiSecret is required for private endpoints");let s=Buffer.from(this.apiSecret,"base64"),o=createHash("sha256").update(r+n).digest(),a=createHmac("sha512",s);return a.update(e),a.update(o),a.digest("base64")}async scheduleWithRetry(e,r){let n=v(e)?this.tradingLimiter:this.restLimiter,s=v(e)?this.tradingCostFn(e):this.restCostFn(e),o=()=>n?n.schedule(r,{cost:s}):r();if(!this.rateLimitOptions.retryOnRateLimit)return o();let a=this.rateLimitOptions.maxRetries,i=0;for(;;)try{return await o()}catch(l){i++;let d=l?.message??(typeof l=="string"?l:"")??"",c=l?.krakenErrorCodes??l?.krakenErrors,k=d.includes("EAPI:Rate limit exceeded")||Array.isArray(c)&&c.some(g=>g.includes("EAPI:Rate limit exceeded")),u=(()=>{let g=M(d);if(g)return g;if(Array.isArray(c))for(let G of c){let C=M(G);if(C)return C}return null})(),p=l?.httpStatus===429;if(!(k||u!==null||p)||i>a)throw l;let m=0;if(u!==null){let g=Math.floor(Date.now()/1e3);m=Math.max(0,u-g)*1e3;}else {let g=250*Math.pow(2,i-1);m=Math.min(g,1e4);}m=D(m),this.logger?.warn?.("Kraken rate limited; retrying",{endpoint:e,attempt:i,waitMs:m,reason:p?"HTTP 429":u?"EService: Throttled":"EAPI: Rate limit exceeded"}),await w(m);}}};function F(t){return t.publicGet("/0/public/Time")}function H(t){return t.publicGet("/0/public/SystemStatus")}function j(t,e){let r={};return e?.asset&&e.asset.length>0&&(r.asset=e.asset.join(",")),e?.aclass&&(r.aclass=e.aclass),t.publicGet("/0/public/Assets",r)}function Q(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.aclass_base&&(r.aclass_base=e.aclass_base),e?.info&&(r.info=e.info),e?.country_code&&(r.country_code=e.country_code),t.publicGet("/0/public/AssetPairs",r)}function N(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Ticker",r)}async function V(t,e){let r={pair:e.pair};e.interval!==void 0&&(r.interval=String(e.interval)),e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/OHLC",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,ohlc:a}}function z(t,e){let r={pair:e.pair};return e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Depth",r)}async function $(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Trades",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,trades:a}}async function J(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Spread",r),{last:s,...o}=n,a={};for(let[i,l]of Object.entries(o))a[i]=l;return {last:s,spreads:a}}var x=class{constructor(e){this.base=e;}getServerTime(){return F(this.base)}getSystemStatus(){return H(this.base)}getAssetInfo(e){return j(this.base,e)}getTradableAssetPairs(e){return Q(this.base,e)}getTickerInformation(e){return N(this.base,e)}getOhlcData(e){return V(this.base,e)}getOrderBook(e){return z(this.base,e)}getRecentTrades(e){return $(this.base,e)}getRecentSpreads(e){return J(this.base,e)}};function Y(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Balance",r)}function X(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/BalanceEx",r)}function Z(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/CreditLines",r)}function ee(t,e){let r={};return e?.asset&&(r.asset=e.asset),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeBalance",r)}function re(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenOrders",r)}function te(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.closetime&&(r.closetime=e.closetime),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/ClosedOrders",r)}function ne(t,e){let r={};return e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.userref!==void 0&&(r.userref=String(e.userref)),Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryOrders",r)}function se(t,e){let r={order_id:e.order_id};return e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OrderAmends",r)}function ae(t,e){let r={};return e?.type&&(r.type=e.type),e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.ledgers!==void 0&&(r.ledgers=e.ledgers?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradesHistory",r)}function oe(t,e){let r={};return Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryTrades",r)}function ie(t,e){let r={};return e?.txid!==void 0&&(r.txid=Array.isArray(e.txid)?e.txid.join(","):e.txid),e?.docalcs!==void 0&&(r.docalcs=e.docalcs?"true":"false"),e?.consolidation&&(r.consolidation=e.consolidation),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenPositions",r)}function de(t,e){let r={};return e?.asset!==void 0&&(r.asset=Array.isArray(e.asset)?e.asset.join(","):e.asset),e?.aclass&&(r.aclass=e.aclass),e?.type&&(r.type=e.type),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Ledgers",r)}function ce(t,e){let r={};return Array.isArray(e.id)?r.id=e.id.join(","):r.id=e.id,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryLedgers",r)}function le(t,e){let r={};return e?.pair!==void 0&&(r.pair=Array.isArray(e.pair)?e.pair.join(","):e.pair),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeVolume",r)}function pe(t,e){let r={report:e.report,description:e.description};return e.format&&(r.format=e.format),e.fields&&(r.fields=e.fields),e.starttm!==void 0&&(r.starttm=String(e.starttm)),e.endtm!==void 0&&(r.endtm=String(e.endtm)),t.privatePost("/0/private/AddExport",r)}function ue(t,e){let r={report:e.report};return t.privatePost("/0/private/ExportStatus",r)}function ke(t,e){let r={id:e.id};return t.privatePostBinary("/0/private/RetrieveExport",r)}function Ke(t,e){let r={id:e.id,type:e.type};return t.privatePost("/0/private/RemoveExport",r)}var W=class{constructor(e){this.base=e;}getAccountBalance(e){return Y(this.base,e)}getExtendedBalance(e){return X(this.base,e)}getCreditLines(e){return Z(this.base,e)}getTradeBalance(e){return ee(this.base,e)}getOpenOrders(e){return re(this.base,e)}getClosedOrders(e){return te(this.base,e)}queryOrdersInfo(e){return ne(this.base,e)}getOrderAmends(e){return se(this.base,e)}getTradesHistory(e){return ae(this.base,e)}queryTradesInfo(e){return oe(this.base,e)}getOpenPositions(e){return ie(this.base,e)}getLedgersInfo(e){return de(this.base,e)}queryLedgers(e){return ce(this.base,e)}getTradeVolume(e){return le(this.base,e)}requestExportReport(e){return pe(this.base,e)}getExportReportStatus(e){return ue(this.base,e)}retrieveExportReport(e){return ke(this.base,e)}deleteExportReport(e){return Ke(this.base,e)}};function me(t,e){if(e.userref!==void 0&&e.cl_ord_id)throw new Error("KrakenAddOrderParams: userref and cl_ord_id are mutually exclusive");let r={ordertype:e.ordertype,type:e.type,volume:e.volume,pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.displayvol&&(r.displayvol=e.displayvol),e.asset_class&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.trigger&&(r.trigger=e.trigger),e.leverage!==void 0&&(r.leverage=e.leverage),e.reduce_only!==void 0&&(r.reduce_only=e.reduce_only?"true":"false"),e.stptype&&(r.stptype=e.stptype),e.oflags&&(r.oflags=e.oflags),e.timeinforce&&(r.timeinforce=e.timeinforce),e.starttm!==void 0&&(r.starttm=e.starttm),e.expiretm!==void 0&&(r.expiretm=e.expiretm),e.deadline!==void 0&&(r.deadline=e.deadline),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),e.close&&(r["close[ordertype]"]=e.close.ordertype,e.close.price!==void 0&&(r["close[price]"]=e.close.price),e.close.price2!==void 0&&(r["close[price2]"]=e.close.price2)),t.privatePost("/0/private/AddOrder",r)}function be(t,e){if(!e.txid&&!e.cl_ord_id)throw new Error("KrakenAmendOrderParams: either txid or cl_ord_id must be provided");let r={};return e.txid&&(r.txid=e.txid),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.order_qty!==void 0&&(r.order_qty=e.order_qty),e.display_qty!==void 0&&(r.display_qty=e.display_qty),e.limit_price!==void 0&&(r.limit_price=e.limit_price),e.trigger_price!==void 0&&(r.trigger_price=e.trigger_price),e.pair!==void 0&&(r.pair=e.pair),e.post_only!==void 0&&(r.post_only=e.post_only?"true":"false"),e.deadline!==void 0&&(r.deadline=e.deadline),t.privatePost("/0/private/AmendOrder",r)}function ge(t,e){let{txid:r,userref:n,cl_ord_id:s}=e,o=(r!==void 0?1:0)+(n!==void 0?1:0)+(s!==void 0?1:0);if(o===0)throw new Error("KrakenCancelOrderParams: one of txid, userref, or cl_ord_id must be provided");if(o>1)throw new Error("KrakenCancelOrderParams: txid, userref, and cl_ord_id are mutually exclusive; provide exactly one");let a={};return n!==void 0?a.txid=String(n):s!==void 0?a.cl_ord_id=Array.isArray(s)?s.join(","):s:r!==void 0&&(a.txid=Array.isArray(r)?r.join(","):r),t.privatePost("/0/private/CancelOrder",a)}function ye(t){return t.privatePost("/0/private/CancelAll",{})}function fe(t,e){let r={timeout:String(e.timeout)};return t.privatePost("/0/private/CancelAllOrdersAfter",r)}function he(t){return t.privatePost("/0/private/GetWebSocketsToken",{})}function xe(t,e){let{orders:r,pair:n,asset_class:s,deadline:o,validate:a}=e;if(!Array.isArray(r)||r.length<2||r.length>15)throw new Error(`KrakenAddOrderBatchParams: orders must contain between 2 and 15 items (got ${r.length})`);for(let[d,c]of r.entries())if(c.userref!==void 0&&c.cl_ord_id!==void 0)throw new Error(`KrakenAddOrderBatchParams: order[${d}] cannot have both userref and cl_ord_id`);let i={pair:n};s&&(i.asset_class=s),o!==void 0&&(i.deadline=o),a!==void 0&&(i.validate=a?"true":"false");let l=r.map(d=>{let c={ordertype:d.ordertype,type:d.type,volume:d.volume};return d.userref!==void 0&&(c.userref=String(d.userref)),d.cl_ord_id!==void 0&&(c.cl_ord_id=d.cl_ord_id),d.displayvol!==void 0&&(c.displayvol=d.displayvol),d.price!==void 0&&(c.price=d.price),d.price2!==void 0&&(c.price2=d.price2),d.trigger!==void 0&&(c.trigger=d.trigger),d.leverage!==void 0&&(c.leverage=d.leverage),d.reduce_only!==void 0&&(c.reduce_only=d.reduce_only?"true":"false"),d.stptype!==void 0&&(c.stptype=d.stptype),d.oflags!==void 0&&(c.oflags=d.oflags),d.timeinforce!==void 0&&(c.timeinforce=d.timeinforce),d.starttm!==void 0&&(c.starttm=d.starttm),d.expiretm!==void 0&&(c.expiretm=d.expiretm),c});return i.orders=JSON.stringify(l),t.privatePost("/0/private/AddOrderBatch",i)}function We(t,e){let{orders:r,clOrdIds:n}=e,s=r?.length??0,o=n?.length??0,a=s+o;if(a===0)throw new Error("KrakenCancelOrderBatchParams: at least one txid/userref or cl_ord_id is required");if(a>50)throw new Error(`KrakenCancelOrderBatchParams: maximum 50 total ids/references allowed, got ${a}`);let i={};if(r&&r.length>0){let l=r.map(d=>({txid:String(d.txid)}));i.orders=JSON.stringify(l);}if(n&&n.length>0){let l=n.map(d=>({cl_ord_id:d}));i.cl_ord_ids=JSON.stringify(l);}return t.privatePost("/0/private/CancelOrderBatch",i)}function Oe(t,e){let r={txid:String(e.txid),pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.volume!==void 0&&(r.volume=e.volume),e.displayvol!==void 0&&(r.displayvol=e.displayvol),e.asset_class!==void 0&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.oflags!==void 0&&(r.oflags=e.oflags),e.deadline!==void 0&&(r.deadline=e.deadline),e.cancel_response!==void 0&&(r.cancel_response=e.cancel_response?"true":"false"),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),t.privatePost("/0/private/EditOrder",r)}var O=class{constructor(e){this.base=e;}addOrder(e){return me(this.base,e)}amendOrder(e){return be(this.base,e)}cancelOrder(e){return ge(this.base,e)}cancelAllOrders(){return ye(this.base)}cancelAllOrdersAfter(e){return fe(this.base,e)}getWebSocketsToken(){return he(this.base)}addOrderBatch(e){return xe(this.base,e)}cancelOrderBatch(e){return We(this.base,e)}editOrder(e){return Oe(this.base,e)}};function Re(t,e){let r={asset:e.asset};return e.aclass!==void 0&&(r.aclass=e.aclass),e.rebase_multiplier!==void 0&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositMethods",r)}function Ae(t,e){let r={asset:e.asset,method:e.method};return e.aclass!==void 0&&(r.aclass=e.aclass),e.new!==void 0&&(r.new=e.new?"true":"false"),e.amount!==void 0&&(r.amount=String(e.amount)),t.privatePost("/0/private/DepositAddresses",r)}function Te(t,e={}){let r={};return e.asset&&(r.asset=e.asset),e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.start!==void 0&&(r.start=String(e.start)),e.end!==void 0&&(r.end=String(e.end)),e.cursor&&(r.cursor=e.cursor),e.limit!==void 0&&(r.limit=String(e.limit)),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositStatus",r)}function Pe(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.network&&(r.network=e.network),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/WithdrawMethods",r)}function Se(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.key&&(r.key=e.key),e.verified!==void 0&&(r.verified=e.verified?"true":"false"),t.privatePost("/0/private/WithdrawAddresses",r)}function Be(t,e){let r={asset:e.asset,key:e.key,amount:String(e.amount)};return t.privatePost("/0/private/WithdrawInfo",r)}function _e(t,e){let{asset:r,aclass:n,key:s,address:o,amount:a,max_fee:i,rebase_multiplier:l}=e,d={asset:r,key:s,amount:String(a)};return n&&(d.aclass=n),o&&(d.address=o),i!==void 0&&(d.max_fee=String(i)),l&&(d.rebase_multiplier=l),t.privatePost("/0/private/Withdraw",d)}async function Ee(t,e={}){let{asset:r,aclass:n,method:s,start:o,end:a,cursor:i,limit:l,rebase_multiplier:d}=e,c={};return r&&(c.asset=r),n&&(c.aclass=n),s&&(c.method=s),o!==void 0&&(c.start=o),a!==void 0&&(c.end=a),i!==void 0&&(c.cursor=i),l!==void 0&&(c.limit=l),d&&(c.rebase_multiplier=d),t.privatePost("/0/private/WithdrawStatus",c)}function ve(t,e){let{asset:r,refid:n}=e,s={asset:r,refid:n};return t.privatePost("/0/private/WithdrawCancel",s)}function we(t,e){let{asset:r,from:n,to:s,amount:o}=e,a={asset:r,from:n,to:s,amount:String(o)};return t.privatePost("/0/private/WalletTransfer",a)}var R=class{constructor(e){this.base=e;}getDepositMethods(e){return Re(this.base,e)}getDepositAddresses(e){return Ae(this.base,e)}getDepositStatus(e={}){return Te(this.base,e)}getWithdrawMethods(e){return Pe(this.base,e)}getWithdrawAddresses(e){return Se(this.base,e)}getWithdrawInfo(e){return Be(this.base,e)}withdrawFunds(e){return _e(this.base,e)}getWithdrawStatus(e={}){return Ee(this.base,e)}withdrawCancel(e){return ve(this.base,e)}walletTransfer(e){return we(this.base,e)}};async function Me(t,e){let{username:r,email:n}=e,s={username:r,email:n};return t.privatePost("/0/private/CreateSubaccount",s)}async function Ge(t,e){let{asset:r,asset_class:n,amount:s,from:o,to:a}=e,i={asset:r,amount:String(s),from:o,to:a};return n&&(i.asset_class=n),t.privatePost("/0/private/AccountTransfer",i)}var A=class{constructor(e){this.base=e;}createSubaccount(e){return Me(this.base,e)}accountTransfer(e){return Ge(this.base,e)}};async function Ce(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Allocate",s)}async function Ie(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Deallocate",s)}async function Le(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/AllocateStatus",n)}async function De(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/DeallocateStatus",n)}async function qe(t,e={}){let{ascending:r,asset:n,cursor:s,limit:o,lock_type:a}=e,i={};return r!=null&&(i.ascending=r),n!=null&&(i.asset=n),s!=null&&(i.cursor=s),o!=null&&(i.limit=o),a&&a.length>0&&(i.lock_type=JSON.stringify(a)),t.privatePost("/0/private/Earn/Strategies",i)}async function Ue(t,e={}){let{ascending:r,converted_asset:n,hide_zero_allocations:s}=e,o={};return r!=null&&(o.ascending=r),n!=null&&(o.converted_asset=n),s!=null&&(o.hide_zero_allocations=s),t.privatePost("/0/private/Earn/Allocations",o)}var T=class{constructor(e){this.base=e;}allocateFunds(e){return Ce(this.base,e)}deallocateFunds(e){return Ie(this.base,e)}getAllocationStatus(e){return Le(this.base,e)}getDeallocationStatus(e){return De(this.base,e)}listStrategies(e={}){return qe(this.base,e)}listAllocations(e={}){return Ue(this.base,e)}};async function Fe(t,e){let{symbol:r}=e,s={symbol:typeof r=="string"?r:r.join(",")};return t.publicGet("/0/public/PreTrade",s)}async function He(t,e={}){let{symbol:r,from_ts:n,to_ts:s,count:o}=e,a={};return r&&(a.symbol=r),n&&(a.from_ts=n),s&&(a.to_ts=s),o!==void 0&&(a.count=o),t.publicGet("/0/public/PostTrade",a)}var P=class{constructor(e){this.base=e;}getPreTradeData(e){return Fe(this.base,e)}getPostTradeData(e={}){return He(this.base,e)}};var je=class extends h{marketData;accountData;trading;funding;subaccounts;earn;transparency;constructor(e={}){super(e),this.marketData=new x(this),this.accountData=new W(this),this.trading=new O(this),this.funding=new R(this),this.subaccounts=new A(this),this.earn=new T(this),this.transparency=new P(this);}};var y=class{url;authToken;WebSocketImpl;logger;autoReconnect;reconnectDelayMs;requestTimeoutMs;ws=null;connectingPromise=null;manuallyClosed=false;nextReqId=1;pending=new Map;messageHandlers=new Set;reconnectAttempts=0;constructor(e){if(this.url=e.url,this.authToken=e.authToken,this.WebSocketImpl=e.WebSocketImpl??(typeof WebSocket<"u"?WebSocket:void 0),this.logger=e.logger,this.autoReconnect=e.autoReconnect??true,this.reconnectDelayMs=e.reconnectDelayMs??1e3,this.requestTimeoutMs=e.requestTimeoutMs??1e4,!this.WebSocketImpl)throw new Error("No WebSocket implementation available. Pass `WebSocketImpl` in KrakenWebsocketConnectionOptions when using Node.js.")}get readyState(){return this.ws?.readyState??-1}async connect(){if(!(this.ws&&this.ws.readyState===1))return this.connectingPromise?this.connectingPromise:(this.manuallyClosed=false,this.connectingPromise=new Promise((e,r)=>{try{let n=this.WebSocketImpl,s=new n(this.url);this.ws=s,s.onopen=()=>{this.reconnectAttempts=0,this.logger?.info?.("Kraken WS connected",{url:this.url}),this.connectingPromise=null,e();},s.onclose=o=>{this.logger?.info?.("Kraken WS closed",{url:this.url,event:o,manuallyClosed:this.manuallyClosed}),this.ws=null,this.connectingPromise=null;for(let[a,i]of this.pending)clearTimeout(i.timeoutId),i.reject(new Error(`WebSocket closed before response for req_id ${a}`));if(this.pending.clear(),!this.manuallyClosed&&this.autoReconnect){this.reconnectAttempts++;let a=this.reconnectDelayMs,i=Math.min(3e4,a*Math.pow(2,this.reconnectAttempts-1)),l=this.reconnectAttempts>=4?5e3:0,d=Math.max(l,i),c=Math.max(0,Math.floor(d*(.8+Math.random()*.4)));setTimeout(()=>{this.logger?.info?.("Kraken WS reconnecting",{url:this.url,attempt:this.reconnectAttempts,delayMs:c}),this.connect().catch(k=>{this.logger?.error?.("Kraken WS reconnect failed",{url:this.url,error:k});});},c);}},s.onerror=o=>{this.logger?.error?.("Kraken WS error",{url:this.url,event:o});},s.onmessage=o=>{let a=o.data;if(typeof o.data=="string")try{a=JSON.parse(o.data);}catch(i){this.logger?.warn?.("Failed to parse WS JSON message",{data:o.data,error:i});}if(a&&typeof a=="object"&&"req_id"in a&&typeof a.req_id=="number"){let i=a.req_id,l=this.pending.get(i);l&&(this.pending.delete(i),clearTimeout(l.timeoutId),l.resolve(a));}for(let i of this.messageHandlers)try{i(a);}catch(l){this.logger?.error?.("WS message handler threw",{error:l});}};}catch(n){this.connectingPromise=null,r(n);}}),this.connectingPromise)}close(e,r){this.manuallyClosed=true,this.ws&&this.ws.readyState===1&&this.ws.close(e,r);}addMessageHandler(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}async sendRaw(e){(!this.ws||this.ws.readyState!==1)&&await this.connect();let r=this.ws;if(!r||r.readyState!==1)throw new Error("WebSocket is not open");let n=typeof e=="string"?e:JSON.stringify(e);r.send(n);}async request(e,r,n){(!this.ws||this.ws.readyState!==1)&&await this.connect();let s=n?.reqId??this.nextReqId++,o=n?.timeoutMs??this.requestTimeoutMs,a=n?.attachAuthToken??true,i=r?{...r}:{};a&&this.authToken&&(i.token===void 0||i.token===null)&&(i.token=this.authToken);let l={method:e,params:Object.keys(i).length?i:void 0,req_id:s};return this.logger?.debug?.("Kraken WS request",{envelope:l}),await new Promise((d,c)=>{let k=setTimeout(()=>{this.pending.delete(s),c(new Error(`Kraken WS request timed out after ${o}ms (method=${e}, req_id=${s})`));},o),u={resolve:p=>d(p),reject:c,timeoutId:k};this.pending.set(s,u);try{let p=this.ws;if(!p||p.readyState!==1){clearTimeout(k),this.pending.delete(s),c(new Error(`WebSocket is not open (method=${e}, req_id=${s})`));return}p.send(JSON.stringify(l));}catch(p){clearTimeout(k),this.pending.delete(s),c(p);}})}};function Ne(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="status"&&n.type==="update"&&Array.isArray(n.data)&&e(n);})}async function Ve(t,e={},r={}){return t.request("ping",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}function ze(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="heartbeat"&&e(n);})}var S=class{constructor(e){this.ws=e;}ping(e={},r={}){return Ve(this.ws,e,r)}onStatus(e){return Ne(this.ws,e)}onHeartbeat(e){return ze(this.ws,e)}};async function $e(t,e,r={}){let n={channel:"ticker",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Je(t,e,r={}){let n={channel:"ticker",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Ye(t,e,r={}){let n={channel:"book",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Xe(t,e,r={}){let n={channel:"book",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Ze(t,e,r={}){let n={channel:"level3",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function er(t,e,r={}){let n={channel:"level3",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function rr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function tr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function nr(t,e,r={}){let n={channel:"trade",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function sr(t,e,r={}){let n={channel:"trade",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function ar(t,e={},r={}){let n={channel:"instrument",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function or(t,e={},r={}){let n={channel:"instrument",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}var B=class{constructor(e){this.ws=e;}subscribeTicker(e,r={}){return $e(this.ws,e,r)}unsubscribeTicker(e,r={}){return Je(this.ws,e,r)}subscribeBook(e,r={}){return Ye(this.ws,e,r)}unsubscribeBook(e,r={}){return Xe(this.ws,e,r)}subscribeLevel3(e,r={}){return Ze(this.ws,e,r)}unsubscribeLevel3(e,r={}){return er(this.ws,e,r)}subscribeOhlc(e,r={}){return rr(this.ws,e,r)}unsubscribeOhlc(e,r={}){return tr(this.ws,e,r)}subscribeTrade(e,r={}){return nr(this.ws,e,r)}unsubscribeTrade(e,r={}){return sr(this.ws,e,r)}subscribeInstrument(e={},r={}){return ar(this.ws,e,r)}unsubscribeInstrument(e={},r={}){return or(this.ws,e,r)}};async function ir(t,e,r={}){let n={channel:"executions",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function dr(t,e={},r={}){let n={channel:"executions",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function cr(t,e={},r={}){let n={channel:"balances",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function lr(t,e={},r={}){let n={channel:"balances",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}var _=class{constructor(e){this.ws=e;}subscribeExecutions(e,r){return ir(this.ws,e,r)}unsubscribeExecutions(e,r){return dr(this.ws,e??{},r)}subscribeBalances(e={},r){return cr(this.ws,e,r)}unsubscribeBalances(e,r){return lr(this.ws,e??{},r)}};async function pr(t,e,r={}){return t.request("add_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function ur(t,e,r={}){let n=!!e.order_id,s=!!e.cl_ord_id;if(n&&s||!n&&!s)throw new Error("Kraken WS amend_order: exactly one of `order_id` or `cl_ord_id` must be provided");return t.request("amend_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function kr(t,e,r={}){return t.request("edit_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Kr(t,e,r={}){let n=Array.isArray(e.order_id)&&e.order_id.length>0,s=Array.isArray(e.cl_ord_id)&&e.cl_ord_id.length>0,o=Array.isArray(e.order_userref)&&e.order_userref.length>0;if(!n&&!s&&!o)throw new Error("Kraken WS cancel_order: at least one of `order_id`, `cl_ord_id`, or `order_userref` must contain at least one entry");return t.request("cancel_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function mr(t,e={},r={}){return t.request("cancel_all",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function br(t,e,r={}){if(!Number.isFinite(e.timeout))throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be a finite number (seconds)");if(e.timeout<0||e.timeout>=86400)throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be >= 0 and < 86400 seconds");return t.request("cancel_all_orders_after",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function gr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_add: `orders` must contain at least 2 entries");if(e.orders.length>15)throw new Error("Kraken WS batch_add: `orders` must not contain more than 15 entries");for(let[n,s]of e.orders.entries())if(s.cl_ord_id&&typeof s.order_userref=="number")throw new Error(`Kraken WS batch_add: order at index ${n} must not specify both cl_ord_id and order_userref`);return t.request("batch_add",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function yr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_cancel: `orders` must contain at least 2 identifiers");if(e.orders.length>50)throw new Error("Kraken WS batch_cancel: `orders` must not contain more than 50 identifiers");return t.request("batch_cancel",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}var E=class{constructor(e){this.ws=e;}addOrder(e,r){return pr(this.ws,e,r)}amendOrder(e,r){return ur(this.ws,e,r)}editOrder(e,r){return kr(this.ws,e,r)}cancelOrder(e,r){return Kr(this.ws,e,r)}cancelAll(e,r){return mr(this.ws,e??{},r)}cancelAllOrdersAfter(e,r){return br(this.ws,e,r)}batchAdd(e,r){return gr(this.ws,e,r)}batchCancel(e,r){return yr(this.ws,e,r)}};var fr=class{publicConnection;privateConnection;admin;marketData;userData;userTrading;constructor(e={}){let{publicUrl:r="wss://ws.kraken.com/v2",privateUrl:n="wss://ws-auth.kraken.com/v2",authToken:s,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:l,logger:d}=e,c={authToken:void 0,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:l,logger:d};this.publicConnection=new y({...c,url:r}),this.privateConnection=new y({...c,url:n,authToken:s}),this.admin=new S(this.publicConnection),this.marketData=new B(this.publicConnection),this.userData=new _(this.privateConnection),this.userTrading=new E(this.privateConnection);}};
2
- export{W as KrakenSpotAccountDataApi,T as KrakenSpotEarnApi,R as KrakenSpotFundingApi,x as KrakenSpotMarketDataApi,je as KrakenSpotRestClient,A as KrakenSpotSubaccountsApi,O as KrakenSpotTradingApi,P as KrakenSpotTransparencyApi,fr as KrakenSpotWebsocketV2Client,y as KrakenWebsocketBase};//# sourceMappingURL=index.js.map
1
+ import {createHash,createHmac}from'crypto';import {WebSocket}from'ws';import vn from'os';import m from'path';import {stat,writeFile,readdir,rm,rename}from'fs/promises';import Gr from'fs';import {pipeline}from'stream/promises';import {google}from'googleapis';import Wn from'yauzl';import {parse}from'csv-parse';var A=class{constructor(e,r){this.maxCounter=e;this.decayPerSec=r;}counter=0;lastTs=Date.now();queue=[];draining=false;schedule(e,r){let n=Math.max(0,r?.cost??1);return new Promise((s,o)=>{this.queue.push({fn:e,resolve:s,reject:o,cost:n}),this.drain();})}decayNow(){let e=Date.now(),r=(e-this.lastTs)/1e3;r>0&&(this.counter=Math.max(0,this.counter-r*this.decayPerSec),this.lastTs=e);}async drain(){if(!this.draining){this.draining=true;try{for(;this.queue.length>0;){this.decayNow();let e=this.queue[0];if(this.counter+e.cost<=this.maxCounter){this.queue.shift(),this.counter+=e.cost;try{let o=await e.fn();e.resolve(o);}catch(o){e.reject(o);}continue}let n=(this.counter+e.cost-this.maxCounter)/this.decayPerSec,s=Math.max(50,Math.ceil(n*1e3));await V(s);}}finally{this.draining=false;}}}};function X(t){switch(t){case "pro":return {maxCounter:20,decayPerSec:1};case "intermediate":return {maxCounter:20,decayPerSec:.5};case "starter":default:return {maxCounter:15,decayPerSec:.33}}}function ee(t){return t.includes("TradesHistory")||t.includes("Ledgers")||t.includes("TradeBalance")?2:1}function j(t){return t.includes("/AddOrder")||t.includes("/CancelOrder")||t.includes("/CancelAll")||t.includes("/EditOrder")||t.includes("/AddOrderBatch")||t.includes("/CancelOrderBatch")}function V(t){return new Promise(e=>setTimeout(e,t))}function re(t){let e=t*.2;return Math.max(0,Math.floor(t+(Math.random()*2-1)*e))}function $(t){let e=t.match(/EService:\s*Throttled:\s*(\d+)/i);if(!e)return null;let r=Number(e[1]);return Number.isFinite(r)?r:null}var x=class extends Error{name="KrakenApiError";endpoint;httpStatus;httpStatusText;krakenErrorCodes;rawBody;constructor(e,r={}){super(e),Object.setPrototypeOf(this,new.target.prototype),this.endpoint=r.endpoint,this.httpStatus=r.httpStatus,this.httpStatusText=r.httpStatusText,this.krakenErrorCodes=r.krakenErrorCodes,this.rawBody=r.rawBody;}},h=class extends Error{code;meta;constructor(e,r,n){super(r),this.name="KrakenBulkError",this.code=e,this.meta=n;}};var T=class{baseUrl;timeoutMs;userAgent;apiKey;apiSecret;logger;lastNonce;lastMs=0;restLimiter;tradingLimiter;rateLimitOptions;restCostFn;tradingCostFn;constructor(e={}){this.baseUrl=e.baseUrl??"https://api.kraken.com",this.timeoutMs=e.timeoutMs??1e4,this.userAgent=e.userAgent,this.apiKey=e.apiKey,this.apiSecret=e.apiSecret,this.logger=e.logger;let r=e.rateLimit??{},n=r.mode??"auto",s=r.tier??"starter";if(this.rateLimitOptions={retryOnRateLimit:r.retryOnRateLimit??true,maxRetries:r.maxRetries??5},this.restCostFn=r.restCostFn??ee,this.tradingCostFn=r.tradingCostFn??(()=>1),e.limiter?.rest&&(this.restLimiter=e.limiter.rest),e.limiter?.trading&&(this.tradingLimiter=e.limiter.trading),n!=="off"){if(!this.restLimiter){let{maxCounter:o,decayPerSec:a}=X(s);this.restLimiter=new A(o,a);}this.tradingLimiter||(this.tradingLimiter=new A(10,1));}}createNonce(){let e=Date.now();return this.lastNonce===void 0?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e,this.lastNonce.toString()):(e>this.lastMs?(this.lastNonce=BigInt(e)*1000n,this.lastMs=e):this.lastNonce=this.lastNonce+1n,this.lastNonce.toString())}async publicGet(e,r){let n=new URL(e,this.baseUrl);if(r)for(let[s,o]of Object.entries(r))n.searchParams.set(s,String(o));return this.logger?.debug?.("Kraken REST public GET request",{endpoint:e,url:n.toString(),query:r}),this.scheduleWithRetry(e,async()=>{let s=new AbortController,o=setTimeout(()=>s.abort(),this.timeoutMs);try{let a=await fetch(n,{method:"GET",signal:s.signal,headers:this.userAgent?{"User-Agent":this.userAgent}:void 0});if(!a.ok)throw this.logger?.error?.("Kraken REST HTTP error",{endpoint:e,status:a.status,statusText:a.statusText}),new x(`HTTP error from Kraken: ${a.status} ${a.statusText}`,{endpoint:e,httpStatus:a.status,httpStatusText:a.statusText});let i;try{i=await a.json();}catch(c){throw this.logger?.error?.("Kraken REST JSON parse error",{endpoint:e,error:c}),new x("Failed to parse Kraken response JSON",{endpoint:e,httpStatus:a.status})}if(i.error?.length)throw this.logger?.warn?.("Kraken REST API error",{endpoint:e,krakenErrors:i.error}),new x(`Kraken API error: ${i.error.join(", ")}`,{endpoint:e,httpStatus:a.status,krakenErrorCodes:i.error,rawBody:i});return this.logger?.debug?.("Kraken REST public GET success",{endpoint:e}),i.result}finally{clearTimeout(o);}})}async privatePost(e,r){if(!this.apiKey||!this.apiSecret)throw new x("Missing apiKey or apiSecret for Kraken private API call",{endpoint:e});let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),o=new URLSearchParams;if(o.set("nonce",s),r)for(let[p,g]of Object.entries(r))g!==void 0&&o.set(p,String(g));let a=o.toString(),i=createHash("sha256").update(s+a).digest(),c=Buffer.from(this.apiSecret,"base64"),d=createHmac("sha512",c);d.update(e),d.update(i);let l=d.digest("base64");this.logger?.debug?.("Kraken REST private POST request",{endpoint:e,url:n.toString(),hasParams:!!r});let u=new AbortController,k=setTimeout(()=>u.abort(),this.timeoutMs);try{let p=await fetch(n,{method:"POST",signal:u.signal,headers:{"Content-Type":"application/x-www-form-urlencoded","API-Key":this.apiKey,"API-Sign":l,...this.userAgent?{"User-Agent":this.userAgent}:{}},body:a});if(!p.ok)throw this.logger?.error?.("Kraken REST private HTTP error",{endpoint:e,status:p.status,statusText:p.statusText}),new x(`HTTP error from Kraken private API: ${p.status} ${p.statusText}`,{endpoint:e,httpStatus:p.status,httpStatusText:p.statusText});let g;try{g=await p.json();}catch(y){throw this.logger?.error?.("Kraken REST private JSON parse error",{endpoint:e,error:y}),new x("Failed to parse Kraken private API response JSON",{endpoint:e,httpStatus:p.status})}if(g.error?.length)throw this.logger?.warn?.("Kraken REST private API error",{endpoint:e,krakenErrors:g.error}),new x(`Kraken private API error: ${g.error.join(", ")}`,{endpoint:e,httpStatus:p.status,krakenErrorCodes:g.error,rawBody:g});return this.logger?.debug?.("Kraken REST private POST success",{endpoint:e}),g.result}finally{clearTimeout(k);}})}async privatePostBinary(e,r){if(!this.apiKey||!this.apiSecret)throw new Error("KrakenRestBase: apiKey and apiSecret are required for private endpoints");let n=new URL(e,this.baseUrl);return this.scheduleWithRetry(e,async()=>{let s=this.createNonce(),a=new URLSearchParams({nonce:s,...r??{}}).toString(),i=this.signPrivateRequest(e,s,a);this.logger?.debug?.("[KrakenRestBase] privatePostBinary request",{url:n.toString(),path:e,body:r});let c={"API-Key":this.apiKey,"API-Sign":i,"User-Agent":this.userAgent??"lynx-crypto-kraken-client/0.1.0","Content-Type":"application/x-www-form-urlencoded"},d=await fetch(n.toString(),{method:"POST",headers:c,body:a});if(!d.ok){let k=await d.text().catch(()=>"");throw this.logger?.error?.("[KrakenRestBase] privatePostBinary HTTP error",{status:d.status,statusText:d.statusText,body:k}),new Error(`Kraken privatePostBinary failed: ${d.status} ${d.statusText} \u2013 ${k}`)}if((d.headers.get("content-type")??"").includes("application/json")){let k=await d.json().catch(()=>null);if(!k)throw new Error("Kraken privatePostBinary: expected JSON body for error response");let p=k.error??[];if(p.length>0){let g=`Kraken API error: ${p.join(", ")}`;this.logger?.error?.("[KrakenRestBase] Kraken API error (binary response)",{errors:p});let y=new Error(g);throw y.krakenErrors=p,y}throw new Error("Kraken privatePostBinary: expected binary data but got JSON without errors")}let u=await d.arrayBuffer();return this.logger?.debug?.("[KrakenRestBase] privatePostBinary success",{bytes:u.byteLength}),u})}signPrivateRequest(e,r,n){if(!this.apiSecret)throw new Error("KrakenRestBase: apiSecret is required for private endpoints");let s=Buffer.from(this.apiSecret,"base64"),o=createHash("sha256").update(r+n).digest(),a=createHmac("sha512",s);return a.update(e),a.update(o),a.digest("base64")}async scheduleWithRetry(e,r){let n=j(e)?this.tradingLimiter:this.restLimiter,s=j(e)?this.tradingCostFn(e):this.restCostFn(e),o=()=>n?n.schedule(r,{cost:s}):r();if(!this.rateLimitOptions.retryOnRateLimit)return o();let a=this.rateLimitOptions.maxRetries,i=0;for(;;)try{return await o()}catch(c){i++;let d=c?.message??(typeof c=="string"?c:"")??"",l=c?.krakenErrorCodes??c?.krakenErrors,u=d.includes("EAPI:Rate limit exceeded")||Array.isArray(l)&&l.some(f=>f.includes("EAPI:Rate limit exceeded")),k=(()=>{let f=$(d);if(f)return f;if(Array.isArray(l))for(let W of l){let B=$(W);if(B)return B}return null})(),p=c?.httpStatus===429;if(!(u||k!==null||p)||i>a)throw c;let y=0;if(k!==null){let f=Math.floor(Date.now()/1e3);y=Math.max(0,k-f)*1e3;}else {let f=250*Math.pow(2,i-1);y=Math.min(f,1e4);}y=re(y),this.logger?.warn?.("Kraken rate limited; retrying",{endpoint:e,attempt:i,waitMs:y,reason:p?"HTTP 429":k?"EService: Throttled":"EAPI: Rate limit exceeded"}),await V(y);}}};function se(t){return t.publicGet("/0/public/Time")}function ae(t){return t.publicGet("/0/public/SystemStatus")}function oe(t,e){let r={};return e?.asset&&e.asset.length>0&&(r.asset=e.asset.join(",")),e?.aclass&&(r.aclass=e.aclass),t.publicGet("/0/public/Assets",r)}function ie(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.aclass_base&&(r.aclass_base=e.aclass_base),e?.info&&(r.info=e.info),e?.country_code&&(r.country_code=e.country_code),t.publicGet("/0/public/AssetPairs",r)}function de(t,e){let r={};return e?.pair?.length&&(r.pair=e.pair.join(",")),e?.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Ticker",r)}async function ce(t,e){let r={pair:e.pair};e.interval!==void 0&&(r.interval=String(e.interval)),e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/OHLC",r),{last:s,...o}=n,a={};for(let[i,c]of Object.entries(o))a[i]=c;return {last:s,ohlc:a}}function le(t,e){let r={pair:e.pair};return e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class),t.publicGet("/0/public/Depth",r)}async function ue(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.count!==void 0&&(r.count=String(e.count)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Trades",r),{last:s,...o}=n,a={};for(let[i,c]of Object.entries(o))a[i]=c;return {last:s,trades:a}}async function pe(t,e){let r={pair:e.pair};e.since!==void 0&&(r.since=String(e.since)),e.asset_class&&(r.asset_class=e.asset_class);let n=await t.publicGet("/0/public/Spread",r),{last:s,...o}=n,a={};for(let[i,c]of Object.entries(o))a[i]=c;return {last:s,spreads:a}}var S=class{constructor(e){this.base=e;}getServerTime(){return se(this.base)}getSystemStatus(){return ae(this.base)}getAssetInfo(e){return oe(this.base,e)}getTradableAssetPairs(e){return ie(this.base,e)}getTickerInformation(e){return de(this.base,e)}getOhlcData(e){return ce(this.base,e)}getOrderBook(e){return le(this.base,e)}getRecentTrades(e){return ue(this.base,e)}getRecentSpreads(e){return pe(this.base,e)}};function ke(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Balance",r)}function me(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/BalanceEx",r)}function Ke(t,e){let r={};return e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/CreditLines",r)}function be(t,e){let r={};return e?.asset&&(r.asset=e.asset),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeBalance",r)}function ge(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenOrders",r)}function ye(t,e){let r={};return e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.userref!==void 0&&(r.userref=String(e.userref)),e?.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.closetime&&(r.closetime=e.closetime),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/ClosedOrders",r)}function fe(t,e){let r={};return e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.userref!==void 0&&(r.userref=String(e.userref)),Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryOrders",r)}function he(t,e){let r={order_id:e.order_id};return e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OrderAmends",r)}function xe(t,e){let r={};return e?.type&&(r.type=e.type),e?.trades!==void 0&&(r.trades=e.trades?"true":"false"),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.consolidate_taker!==void 0&&(r.consolidate_taker=e.consolidate_taker?"true":"false"),e?.ledgers!==void 0&&(r.ledgers=e.ledgers?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradesHistory",r)}function We(t,e){let r={};return Array.isArray(e.txid)?r.txid=e.txid.join(","):r.txid=e.txid,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryTrades",r)}function Oe(t,e){let r={};return e?.txid!==void 0&&(r.txid=Array.isArray(e.txid)?e.txid.join(","):e.txid),e?.docalcs!==void 0&&(r.docalcs=e.docalcs?"true":"false"),e?.consolidation&&(r.consolidation=e.consolidation),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/OpenPositions",r)}function Re(t,e){let r={};return e?.asset!==void 0&&(r.asset=Array.isArray(e.asset)?e.asset.join(","):e.asset),e?.aclass&&(r.aclass=e.aclass),e?.type&&(r.type=e.type),e?.start!==void 0&&(r.start=String(e.start)),e?.end!==void 0&&(r.end=String(e.end)),e?.ofs!==void 0&&(r.ofs=String(e.ofs)),e?.without_count!==void 0&&(r.without_count=e.without_count?"true":"false"),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/Ledgers",r)}function Ae(t,e){let r={};return Array.isArray(e.id)?r.id=e.id.join(","):r.id=e.id,e.trades!==void 0&&(r.trades=e.trades?"true":"false"),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/QueryLedgers",r)}function Pe(t,e){let r={};return e?.pair!==void 0&&(r.pair=Array.isArray(e.pair)?e.pair.join(","):e.pair),e?.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/TradeVolume",r)}function Be(t,e){let r={report:e.report,description:e.description};return e.format&&(r.format=e.format),e.fields&&(r.fields=e.fields),e.starttm!==void 0&&(r.starttm=String(e.starttm)),e.endtm!==void 0&&(r.endtm=String(e.endtm)),t.privatePost("/0/private/AddExport",r)}function Te(t,e){let r={report:e.report};return t.privatePost("/0/private/ExportStatus",r)}function Se(t,e){let r={id:e.id};return t.privatePostBinary("/0/private/RetrieveExport",r)}function _e(t,e){let r={id:e.id,type:e.type};return t.privatePost("/0/private/RemoveExport",r)}var _=class{constructor(e){this.base=e;}getAccountBalance(e){return ke(this.base,e)}getExtendedBalance(e){return me(this.base,e)}getCreditLines(e){return Ke(this.base,e)}getTradeBalance(e){return be(this.base,e)}getOpenOrders(e){return ge(this.base,e)}getClosedOrders(e){return ye(this.base,e)}queryOrdersInfo(e){return fe(this.base,e)}getOrderAmends(e){return he(this.base,e)}getTradesHistory(e){return xe(this.base,e)}queryTradesInfo(e){return We(this.base,e)}getOpenPositions(e){return Oe(this.base,e)}getLedgersInfo(e){return Re(this.base,e)}queryLedgers(e){return Ae(this.base,e)}getTradeVolume(e){return Pe(this.base,e)}requestExportReport(e){return Be(this.base,e)}getExportReportStatus(e){return Te(this.base,e)}retrieveExportReport(e){return Se(this.base,e)}deleteExportReport(e){return _e(this.base,e)}};function ve(t,e){if(e.userref!==void 0&&e.cl_ord_id)throw new Error("KrakenAddOrderParams: userref and cl_ord_id are mutually exclusive");let r={ordertype:e.ordertype,type:e.type,volume:e.volume,pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.displayvol&&(r.displayvol=e.displayvol),e.asset_class&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.trigger&&(r.trigger=e.trigger),e.leverage!==void 0&&(r.leverage=e.leverage),e.reduce_only!==void 0&&(r.reduce_only=e.reduce_only?"true":"false"),e.stptype&&(r.stptype=e.stptype),e.oflags&&(r.oflags=e.oflags),e.timeinforce&&(r.timeinforce=e.timeinforce),e.starttm!==void 0&&(r.starttm=e.starttm),e.expiretm!==void 0&&(r.expiretm=e.expiretm),e.deadline!==void 0&&(r.deadline=e.deadline),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),e.close&&(r["close[ordertype]"]=e.close.ordertype,e.close.price!==void 0&&(r["close[price]"]=e.close.price),e.close.price2!==void 0&&(r["close[price2]"]=e.close.price2)),t.privatePost("/0/private/AddOrder",r)}function Ee(t,e){if(!e.txid&&!e.cl_ord_id)throw new Error("KrakenAmendOrderParams: either txid or cl_ord_id must be provided");let r={};return e.txid&&(r.txid=e.txid),e.cl_ord_id&&(r.cl_ord_id=e.cl_ord_id),e.order_qty!==void 0&&(r.order_qty=e.order_qty),e.display_qty!==void 0&&(r.display_qty=e.display_qty),e.limit_price!==void 0&&(r.limit_price=e.limit_price),e.trigger_price!==void 0&&(r.trigger_price=e.trigger_price),e.pair!==void 0&&(r.pair=e.pair),e.post_only!==void 0&&(r.post_only=e.post_only?"true":"false"),e.deadline!==void 0&&(r.deadline=e.deadline),t.privatePost("/0/private/AmendOrder",r)}function we(t,e){let{txid:r,userref:n,cl_ord_id:s}=e,o=(r!==void 0?1:0)+(n!==void 0?1:0)+(s!==void 0?1:0);if(o===0)throw new Error("KrakenCancelOrderParams: one of txid, userref, or cl_ord_id must be provided");if(o>1)throw new Error("KrakenCancelOrderParams: txid, userref, and cl_ord_id are mutually exclusive; provide exactly one");let a={};return n!==void 0?a.txid=String(n):s!==void 0?a.cl_ord_id=Array.isArray(s)?s.join(","):s:r!==void 0&&(a.txid=Array.isArray(r)?r.join(","):r),t.privatePost("/0/private/CancelOrder",a)}function Ie(t){return t.privatePost("/0/private/CancelAll",{})}function Me(t,e){let r={timeout:String(e.timeout)};return t.privatePost("/0/private/CancelAllOrdersAfter",r)}function Ge(t){return t.privatePost("/0/private/GetWebSocketsToken",{})}function Ce(t,e){let{orders:r,pair:n,asset_class:s,deadline:o,validate:a}=e;if(!Array.isArray(r)||r.length<2||r.length>15)throw new Error(`KrakenAddOrderBatchParams: orders must contain between 2 and 15 items (got ${r.length})`);for(let[d,l]of r.entries())if(l.userref!==void 0&&l.cl_ord_id!==void 0)throw new Error(`KrakenAddOrderBatchParams: order[${d}] cannot have both userref and cl_ord_id`);let i={pair:n};s&&(i.asset_class=s),o!==void 0&&(i.deadline=o),a!==void 0&&(i.validate=a?"true":"false");let c=r.map(d=>{let l={ordertype:d.ordertype,type:d.type,volume:d.volume};return d.userref!==void 0&&(l.userref=String(d.userref)),d.cl_ord_id!==void 0&&(l.cl_ord_id=d.cl_ord_id),d.displayvol!==void 0&&(l.displayvol=d.displayvol),d.price!==void 0&&(l.price=d.price),d.price2!==void 0&&(l.price2=d.price2),d.trigger!==void 0&&(l.trigger=d.trigger),d.leverage!==void 0&&(l.leverage=d.leverage),d.reduce_only!==void 0&&(l.reduce_only=d.reduce_only?"true":"false"),d.stptype!==void 0&&(l.stptype=d.stptype),d.oflags!==void 0&&(l.oflags=d.oflags),d.timeinforce!==void 0&&(l.timeinforce=d.timeinforce),d.starttm!==void 0&&(l.starttm=d.starttm),d.expiretm!==void 0&&(l.expiretm=d.expiretm),l});return i.orders=JSON.stringify(c),t.privatePost("/0/private/AddOrderBatch",i)}function De(t,e){let{orders:r,clOrdIds:n}=e,s=r?.length??0,o=n?.length??0,a=s+o;if(a===0)throw new Error("KrakenCancelOrderBatchParams: at least one txid/userref or cl_ord_id is required");if(a>50)throw new Error(`KrakenCancelOrderBatchParams: maximum 50 total ids/references allowed, got ${a}`);let i={};if(r&&r.length>0){let c=r.map(d=>({txid:String(d.txid)}));i.orders=JSON.stringify(c);}if(n&&n.length>0){let c=n.map(d=>({cl_ord_id:d}));i.cl_ord_ids=JSON.stringify(c);}return t.privatePost("/0/private/CancelOrderBatch",i)}function Le(t,e){let r={txid:String(e.txid),pair:e.pair};return e.userref!==void 0&&(r.userref=String(e.userref)),e.volume!==void 0&&(r.volume=e.volume),e.displayvol!==void 0&&(r.displayvol=e.displayvol),e.asset_class!==void 0&&(r.asset_class=e.asset_class),e.price!==void 0&&(r.price=e.price),e.price2!==void 0&&(r.price2=e.price2),e.oflags!==void 0&&(r.oflags=e.oflags),e.deadline!==void 0&&(r.deadline=e.deadline),e.cancel_response!==void 0&&(r.cancel_response=e.cancel_response?"true":"false"),e.validate!==void 0&&(r.validate=e.validate?"true":"false"),t.privatePost("/0/private/EditOrder",r)}var v=class{constructor(e){this.base=e;}addOrder(e){return ve(this.base,e)}amendOrder(e){return Ee(this.base,e)}cancelOrder(e){return we(this.base,e)}cancelAllOrders(){return Ie(this.base)}cancelAllOrdersAfter(e){return Me(this.base,e)}getWebSocketsToken(){return Ge(this.base)}addOrderBatch(e){return Ce(this.base,e)}cancelOrderBatch(e){return De(this.base,e)}editOrder(e){return Le(this.base,e)}};function qe(t,e){let r={asset:e.asset};return e.aclass!==void 0&&(r.aclass=e.aclass),e.rebase_multiplier!==void 0&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositMethods",r)}function Ue(t,e){let r={asset:e.asset,method:e.method};return e.aclass!==void 0&&(r.aclass=e.aclass),e.new!==void 0&&(r.new=e.new?"true":"false"),e.amount!==void 0&&(r.amount=String(e.amount)),t.privatePost("/0/private/DepositAddresses",r)}function Fe(t,e={}){let r={};return e.asset&&(r.asset=e.asset),e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.start!==void 0&&(r.start=String(e.start)),e.end!==void 0&&(r.end=String(e.end)),e.cursor&&(r.cursor=e.cursor),e.limit!==void 0&&(r.limit=String(e.limit)),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/DepositStatus",r)}function He(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.network&&(r.network=e.network),e.rebase_multiplier&&(r.rebase_multiplier=e.rebase_multiplier),t.privatePost("/0/private/WithdrawMethods",r)}function Qe(t,e){let r={asset:e.asset};return e.aclass&&(r.aclass=e.aclass),e.method&&(r.method=e.method),e.key&&(r.key=e.key),e.verified!==void 0&&(r.verified=e.verified?"true":"false"),t.privatePost("/0/private/WithdrawAddresses",r)}function ze(t,e){let r={asset:e.asset,key:e.key,amount:String(e.amount)};return t.privatePost("/0/private/WithdrawInfo",r)}function Ne(t,e){let{asset:r,aclass:n,key:s,address:o,amount:a,max_fee:i,rebase_multiplier:c}=e,d={asset:r,key:s,amount:String(a)};return n&&(d.aclass=n),o&&(d.address=o),i!==void 0&&(d.max_fee=String(i)),c&&(d.rebase_multiplier=c),t.privatePost("/0/private/Withdraw",d)}async function je(t,e={}){let{asset:r,aclass:n,method:s,start:o,end:a,cursor:i,limit:c,rebase_multiplier:d}=e,l={};return r&&(l.asset=r),n&&(l.aclass=n),s&&(l.method=s),o!==void 0&&(l.start=o),a!==void 0&&(l.end=a),i!==void 0&&(l.cursor=i),c!==void 0&&(l.limit=c),d&&(l.rebase_multiplier=d),t.privatePost("/0/private/WithdrawStatus",l)}function Ve(t,e){let{asset:r,refid:n}=e,s={asset:r,refid:n};return t.privatePost("/0/private/WithdrawCancel",s)}function $e(t,e){let{asset:r,from:n,to:s,amount:o}=e,a={asset:r,from:n,to:s,amount:String(o)};return t.privatePost("/0/private/WalletTransfer",a)}var E=class{constructor(e){this.base=e;}getDepositMethods(e){return qe(this.base,e)}getDepositAddresses(e){return Ue(this.base,e)}getDepositStatus(e={}){return Fe(this.base,e)}getWithdrawMethods(e){return He(this.base,e)}getWithdrawAddresses(e){return Qe(this.base,e)}getWithdrawInfo(e){return ze(this.base,e)}withdrawFunds(e){return Ne(this.base,e)}getWithdrawStatus(e={}){return je(this.base,e)}withdrawCancel(e){return Ve(this.base,e)}walletTransfer(e){return $e(this.base,e)}};async function Ze(t,e){let{username:r,email:n}=e,s={username:r,email:n};return t.privatePost("/0/private/CreateSubaccount",s)}async function Ye(t,e){let{asset:r,asset_class:n,amount:s,from:o,to:a}=e,i={asset:r,amount:String(s),from:o,to:a};return n&&(i.asset_class=n),t.privatePost("/0/private/AccountTransfer",i)}var w=class{constructor(e){this.base=e;}createSubaccount(e){return Ze(this.base,e)}accountTransfer(e){return Ye(this.base,e)}};async function Je(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Allocate",s)}async function Xe(t,e){let{amount:r,strategy_id:n}=e,s={amount:String(r),strategy_id:n};return t.privatePost("/0/private/Earn/Deallocate",s)}async function er(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/AllocateStatus",n)}async function rr(t,e){let{strategy_id:r}=e,n={strategy_id:r};return t.privatePost("/0/private/Earn/DeallocateStatus",n)}async function tr(t,e={}){let{ascending:r,asset:n,cursor:s,limit:o,lock_type:a}=e,i={};return r!=null&&(i.ascending=r),n!=null&&(i.asset=n),s!=null&&(i.cursor=s),o!=null&&(i.limit=o),a&&a.length>0&&(i.lock_type=JSON.stringify(a)),t.privatePost("/0/private/Earn/Strategies",i)}async function nr(t,e={}){let{ascending:r,converted_asset:n,hide_zero_allocations:s}=e,o={};return r!=null&&(o.ascending=r),n!=null&&(o.converted_asset=n),s!=null&&(o.hide_zero_allocations=s),t.privatePost("/0/private/Earn/Allocations",o)}var I=class{constructor(e){this.base=e;}allocateFunds(e){return Je(this.base,e)}deallocateFunds(e){return Xe(this.base,e)}getAllocationStatus(e){return er(this.base,e)}getDeallocationStatus(e){return rr(this.base,e)}listStrategies(e={}){return tr(this.base,e)}listAllocations(e={}){return nr(this.base,e)}};async function sr(t,e){let{symbol:r}=e,s={symbol:typeof r=="string"?r:r.join(",")};return t.publicGet("/0/public/PreTrade",s)}async function ar(t,e={}){let{symbol:r,from_ts:n,to_ts:s,count:o}=e,a={};return r&&(a.symbol=r),n&&(a.from_ts=n),s&&(a.to_ts=s),o!==void 0&&(a.count=o),t.publicGet("/0/public/PostTrade",a)}var M=class{constructor(e){this.base=e;}getPreTradeData(e){return sr(this.base,e)}getPostTradeData(e={}){return ar(this.base,e)}};var or=class extends T{marketData;accountData;trading;funding;subaccounts;earn;transparency;constructor(e={}){super(e),this.marketData=new S(this),this.accountData=new _(this),this.trading=new v(this),this.funding=new E(this),this.subaccounts=new w(this),this.earn=new I(this),this.transparency=new M(this);}};var R=class{url;authToken;WebSocketImpl;logger;autoReconnect;reconnectDelayMs;requestTimeoutMs;ws=null;connectingPromise=null;manuallyClosed=false;nextReqId=1;pending=new Map;messageHandlers=new Set;reconnectAttempts=0;constructor(e){if(this.url=e.url,this.authToken=e.authToken,this.WebSocketImpl=e.WebSocketImpl??(typeof WebSocket<"u"?WebSocket:void 0),this.logger=e.logger,this.autoReconnect=e.autoReconnect??true,this.reconnectDelayMs=e.reconnectDelayMs??1e3,this.requestTimeoutMs=e.requestTimeoutMs??1e4,!this.WebSocketImpl)throw new Error("No WebSocket implementation available. Pass `WebSocketImpl` in KrakenWebsocketConnectionOptions when using Node.js.")}get readyState(){return this.ws?.readyState??-1}async connect(){if(!(this.ws&&this.ws.readyState===1))return this.connectingPromise?this.connectingPromise:(this.manuallyClosed=false,this.connectingPromise=new Promise((e,r)=>{try{let n=this.WebSocketImpl,s=new n(this.url);this.ws=s,s.onopen=()=>{this.reconnectAttempts=0,this.logger?.info?.("Kraken WS connected",{url:this.url}),this.connectingPromise=null,e();},s.onclose=o=>{this.logger?.info?.("Kraken WS closed",{url:this.url,event:o,manuallyClosed:this.manuallyClosed}),this.ws=null,this.connectingPromise=null;for(let[a,i]of this.pending)clearTimeout(i.timeoutId),i.reject(new Error(`WebSocket closed before response for req_id ${a}`));if(this.pending.clear(),!this.manuallyClosed&&this.autoReconnect){this.reconnectAttempts++;let a=this.reconnectDelayMs,i=Math.min(3e4,a*Math.pow(2,this.reconnectAttempts-1)),c=this.reconnectAttempts>=4?5e3:0,d=Math.max(c,i),l=Math.max(0,Math.floor(d*(.8+Math.random()*.4)));setTimeout(()=>{this.logger?.info?.("Kraken WS reconnecting",{url:this.url,attempt:this.reconnectAttempts,delayMs:l}),this.connect().catch(u=>{this.logger?.error?.("Kraken WS reconnect failed",{url:this.url,error:u});});},l);}},s.onerror=o=>{this.logger?.error?.("Kraken WS error",{url:this.url,event:o});},s.onmessage=o=>{let a=o.data;if(typeof o.data=="string")try{a=JSON.parse(o.data);}catch(i){this.logger?.warn?.("Failed to parse WS JSON message",{data:o.data,error:i});}if(a&&typeof a=="object"&&"req_id"in a&&typeof a.req_id=="number"){let i=a.req_id,c=this.pending.get(i);c&&(this.pending.delete(i),clearTimeout(c.timeoutId),c.resolve(a));}for(let i of this.messageHandlers)try{i(a);}catch(c){this.logger?.error?.("WS message handler threw",{error:c});}};}catch(n){this.connectingPromise=null,r(n);}}),this.connectingPromise)}close(e,r){this.manuallyClosed=true,this.ws&&this.ws.readyState===1&&this.ws.close(e,r);}addMessageHandler(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}async sendRaw(e){(!this.ws||this.ws.readyState!==1)&&await this.connect();let r=this.ws;if(!r||r.readyState!==1)throw new Error("WebSocket is not open");let n=typeof e=="string"?e:JSON.stringify(e);r.send(n);}async request(e,r,n){(!this.ws||this.ws.readyState!==1)&&await this.connect();let s=n?.reqId??this.nextReqId++,o=n?.timeoutMs??this.requestTimeoutMs,a=n?.attachAuthToken??true,i=r?{...r}:{};a&&this.authToken&&(i.token===void 0||i.token===null)&&(i.token=this.authToken);let c={method:e,params:Object.keys(i).length?i:void 0,req_id:s};return this.logger?.debug?.("Kraken WS request",{envelope:c}),await new Promise((d,l)=>{let u=setTimeout(()=>{this.pending.delete(s),l(new Error(`Kraken WS request timed out after ${o}ms (method=${e}, req_id=${s})`));},o),k={resolve:p=>d(p),reject:l,timeoutId:u};this.pending.set(s,k);try{let p=this.ws;if(!p||p.readyState!==1){clearTimeout(u),this.pending.delete(s),l(new Error(`WebSocket is not open (method=${e}, req_id=${s})`));return}p.send(JSON.stringify(c));}catch(p){clearTimeout(u),this.pending.delete(s),l(p);}})}};function dr(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="status"&&n.type==="update"&&Array.isArray(n.data)&&e(n);})}async function cr(t,e={},r={}){return t.request("ping",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}function lr(t,e){return t.addMessageHandler(r=>{if(!r||typeof r!="object")return;let n=r;n.channel==="heartbeat"&&e(n);})}var G=class{constructor(e){this.ws=e;}ping(e={},r={}){return cr(this.ws,e,r)}onStatus(e){return dr(this.ws,e)}onHeartbeat(e){return lr(this.ws,e)}};async function ur(t,e,r={}){let n={channel:"ticker",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function pr(t,e,r={}){let n={channel:"ticker",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function kr(t,e,r={}){let n={channel:"book",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function mr(t,e,r={}){let n={channel:"book",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Kr(t,e,r={}){let n={channel:"level3",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function br(t,e,r={}){let n={channel:"level3",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function gr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function yr(t,e,r={}){let n={channel:"ohlc",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function fr(t,e,r={}){let n={channel:"trade",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function hr(t,e,r={}){let n={channel:"trade",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function xr(t,e={},r={}){let n={channel:"instrument",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}async function Wr(t,e={},r={}){let n={channel:"instrument",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??false})}var C=class{constructor(e){this.ws=e;}subscribeTicker(e,r={}){return ur(this.ws,e,r)}unsubscribeTicker(e,r={}){return pr(this.ws,e,r)}subscribeBook(e,r={}){return kr(this.ws,e,r)}unsubscribeBook(e,r={}){return mr(this.ws,e,r)}subscribeLevel3(e,r={}){return Kr(this.ws,e,r)}unsubscribeLevel3(e,r={}){return br(this.ws,e,r)}subscribeOhlc(e,r={}){return gr(this.ws,e,r)}unsubscribeOhlc(e,r={}){return yr(this.ws,e,r)}subscribeTrade(e,r={}){return fr(this.ws,e,r)}unsubscribeTrade(e,r={}){return hr(this.ws,e,r)}subscribeInstrument(e={},r={}){return xr(this.ws,e,r)}unsubscribeInstrument(e={},r={}){return Wr(this.ws,e,r)}};async function Or(t,e,r={}){let n={channel:"executions",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function Rr(t,e={},r={}){let n={channel:"executions",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function Ar(t,e={},r={}){let n={channel:"balances",...e};return t.request("subscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}async function Pr(t,e={},r={}){let n={channel:"balances",...e};return t.request("unsubscribe",n,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken??true})}var D=class{constructor(e){this.ws=e;}subscribeExecutions(e,r){return Or(this.ws,e,r)}unsubscribeExecutions(e,r){return Rr(this.ws,e??{},r)}subscribeBalances(e={},r){return Ar(this.ws,e,r)}unsubscribeBalances(e,r){return Pr(this.ws,e??{},r)}};async function Br(t,e,r={}){return t.request("add_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Tr(t,e,r={}){let n=!!e.order_id,s=!!e.cl_ord_id;if(n&&s||!n&&!s)throw new Error("Kraken WS amend_order: exactly one of `order_id` or `cl_ord_id` must be provided");return t.request("amend_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Sr(t,e,r={}){return t.request("edit_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function _r(t,e,r={}){let n=Array.isArray(e.order_id)&&e.order_id.length>0,s=Array.isArray(e.cl_ord_id)&&e.cl_ord_id.length>0,o=Array.isArray(e.order_userref)&&e.order_userref.length>0;if(!n&&!s&&!o)throw new Error("Kraken WS cancel_order: at least one of `order_id`, `cl_ord_id`, or `order_userref` must contain at least one entry");return t.request("cancel_order",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function vr(t,e={},r={}){return t.request("cancel_all",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Er(t,e,r={}){if(!Number.isFinite(e.timeout))throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be a finite number (seconds)");if(e.timeout<0||e.timeout>=86400)throw new Error("Kraken WS cancel_all_orders_after: `timeout` must be >= 0 and < 86400 seconds");return t.request("cancel_all_orders_after",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function wr(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_add: `orders` must contain at least 2 entries");if(e.orders.length>15)throw new Error("Kraken WS batch_add: `orders` must not contain more than 15 entries");for(let[n,s]of e.orders.entries())if(s.cl_ord_id&&typeof s.order_userref=="number")throw new Error(`Kraken WS batch_add: order at index ${n} must not specify both cl_ord_id and order_userref`);return t.request("batch_add",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}async function Ir(t,e,r={}){if(!Array.isArray(e.orders)||e.orders.length<2)throw new Error("Kraken WS batch_cancel: `orders` must contain at least 2 identifiers");if(e.orders.length>50)throw new Error("Kraken WS batch_cancel: `orders` must not contain more than 50 identifiers");return t.request("batch_cancel",e,{reqId:r.reqId,timeoutMs:r.timeoutMs,attachAuthToken:r.attachAuthToken})}var L=class{constructor(e){this.ws=e;}addOrder(e,r){return Br(this.ws,e,r)}amendOrder(e,r){return Tr(this.ws,e,r)}editOrder(e,r){return Sr(this.ws,e,r)}cancelOrder(e,r){return _r(this.ws,e,r)}cancelAll(e,r){return vr(this.ws,e??{},r)}cancelAllOrdersAfter(e,r){return Er(this.ws,e,r)}batchAdd(e,r){return wr(this.ws,e,r)}batchCancel(e,r){return Ir(this.ws,e,r)}};var Mr=class{publicConnection;privateConnection;admin;marketData;userData;userTrading;constructor(e={}){let{publicUrl:r="wss://ws.kraken.com/v2",privateUrl:n="wss://ws-auth.kraken.com/v2",authToken:s,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:c,logger:d}=e,l={authToken:void 0,WebSocketImpl:o,autoReconnect:a,reconnectDelayMs:i,requestTimeoutMs:c,logger:d};this.publicConnection=new R({...l,url:r}),this.privateConnection=new R({...l,url:n,authToken:s}),this.admin=new G(this.publicConnection),this.marketData=new C(this.publicConnection),this.userData=new D(this.privateConnection),this.userTrading=new L(this.privateConnection);}};async function K(t){await Gr.promises.mkdir(t,{recursive:true});}async function b(t){try{return await stat(t),!0}catch{return false}}async function O(t){try{await Gr.promises.rm(t,{recursive:!0,force:!0});}catch{}}function Dr(){return google.drive({version:"v3"})}async function Lr(t){let{folderId:e,apiKey:r,userAgent:n,logger:s}=t,o=Dr();s?.debug?.("Drive API folder listing",{folderId:e});let a=[],i;do{let c=await o.files.list({key:r,q:`'${e}' in parents and trashed = false`,fields:"nextPageToken, files(id, name)",pageSize:1e3,pageToken:i,...n?{headers:{"User-Agent":n}}:{}});for(let d of c.data.files??[])!d.id||!d.name||a.push({id:d.id,name:d.name});i=c.data.nextPageToken??void 0;}while(i);return a}async function qr(t){let{fileId:e,apiKey:r,destinationPath:n,userAgent:s,logger:o,onProgress:a}=t;await K(m.dirname(n));let i=Dr(),c;try{let u=await i.files.get({key:r,fileId:e,fields:"size"}),k=u.data.size?Number(u.data.size):void 0;k!==void 0&&Number.isFinite(k)&&k>0&&(c=k);}catch{}let d=`${n}.tmp.${Date.now()}.${Math.random().toString(16).slice(2)}`,l=0;try{o?.debug?.("Drive API download starting",{fileId:e,destinationPath:n});let k=(await i.files.get({key:r,fileId:e,alt:"media"},{responseType:"stream",...s?{headers:{"User-Agent":s}}:{}})).data;if(!k||typeof k.pipe!="function")throw new Error("Drive download missing response body");return a?.({downloadedBytes:0,totalBytes:c}),k.on("data",p=>{l+=p.length,a?.({downloadedBytes:l,totalBytes:c});}),await pipeline(k,Gr.createWriteStream(d)),await rm(n,{force:!0}).catch(()=>{}),await rename(d,n),a?.({downloadedBytes:l,totalBytes:c}),{bytes:l,totalBytes:c}}catch(u){try{await rm(d,{force:!0});}catch{}let k=u instanceof Error?u.message:String(u);throw o?.error?.("Drive API download failed",{fileId:e,err:k}),u}}async function Fr(t,e,r){await K(e);let n=r?.onProgress,s=Bn(r?.concurrency),o=0,a=_n(n);a({extractedFiles:o});let i=await Rn(t);try{let c=await An(i),d=c.length;return a({extractedFiles:o,totalFiles:d}),await Tn(c,s,async l=>{let u=Sn(e,l.fileName);await K(m.dirname(u)),await Pn(i,l,u),o+=1,a({extractedFiles:o,totalFiles:d,currentFile:l.fileName});}),a({extractedFiles:o,totalFiles:d}),o}finally{try{i.close();}catch{}}}function Rn(t){return new Promise((e,r)=>{Wn.open(t,{lazyEntries:true,autoClose:false},(n,s)=>{if(n||!s)return r(n??new Error("Failed to open ZIP"));e(s);});})}async function An(t){let e=[];return await new Promise((r,n)=>{let s=false,o=a=>{s||(s=true,n(a instanceof Error?a:new Error(String(a))));};t.on("entry",a=>{if(/\/$/.test(a.fileName)){t.readEntry();return}a.fileName.toLowerCase().endsWith(".csv")&&e.push(a),t.readEntry();}),t.on("end",()=>{s||(s=true,r());}),t.on("error",o),t.readEntry();}),e}function Pn(t,e,r){return new Promise((n,s)=>{t.openReadStream(e,async(o,a)=>{if(o||!a){s(o??new Error("ZIP openReadStream failed"));return}let i=Gr.createWriteStream(r);try{await pipeline(a,i),n();}catch(c){try{i.destroy();}catch{}try{Gr.rmSync(r,{force:!0});}catch{}s(c);}});})}function Bn(t){let e=Number.isFinite(t)?Math.floor(t):1;return e<=0?1:Math.min(e,32)}async function Tn(t,e,r){if(t.length===0)return;let n=Math.min(e,t.length),s=0,o=async()=>{for(;;){let a=s++;if(a>=t.length)return;await r(t[a]);}};await Promise.all(Array.from({length:n},()=>o()));}function Sn(t,e){let r=e.replace(/^([/\\])+/,""),n=m.join(t,r),s=m.resolve(t)+m.sep,o=m.resolve(n);if(!o.startsWith(s))throw new Error(`ZIP entry path traversal blocked: ${e}`);return o}function _n(t){if(!t)return n=>{};let e=0,r=-1;return n=>{let s=Date.now(),o=n.extractedFiles!==r,a=s-e>=100;o&&a&&(e=s,r=n.extractedFiles,t(n));}}var q="LYNX_CRYPTO_KRAKEN_API_GOOGLE_DRIVE_API_KEY",Qr=".extracted.ok",zr=".extracting",U=class{logger;userAgent;storageDir;googleDriveApiKey;driveFolderCache=new Map;constructor(e={}){this.logger=e.logger,this.userAgent=e.userAgent,this.googleDriveApiKey=e.googleDriveApiKey??process.env[q];let r=e.storageDir??m.join(vn.homedir(),".lynx-crypto","bulk");this.storageDir=m.isAbsolute(r)?r:m.resolve(process.cwd(),r);}driveApiKeyEnvVar(){return q}hasGoogleDriveApiKey(){return !!this.googleDriveApiKey}getStorageDir(){return this.storageDir}sourceKey(e){return e.type==="complete"?"complete":e.quarter}datasetDir(e){return m.join(this.storageDir,e)}zipsDir(e){return m.join(this.datasetDir(e),"zips")}extractedRootDir(e){return m.join(this.datasetDir(e),"extracted")}zipBucket(e){return e.type==="complete"?"complete":"quarterly"}extractBucket(e){return e.type==="complete"?"complete":"quarterly"}zipsBucketDir(e,r){return m.join(this.zipsDir(e),this.zipBucket(r))}extractedBucketDir(e,r){return r.type==="complete"?m.join(this.extractedRootDir(e),"complete"):m.join(this.extractedRootDir(e),"quarterly",r.quarter)}zipPath(e,r){return m.join(this.zipsBucketDir(e,r),`${this.sourceKey(r)}.zip`)}extractedDir(e,r){return this.extractedBucketDir(e,r)}async ensureDatasetDirs(e){await K(this.datasetDir(e)),await K(this.zipsDir(e)),await K(m.join(this.zipsDir(e),"complete")),await K(m.join(this.zipsDir(e),"quarterly")),await K(this.extractedRootDir(e)),await K(m.join(this.extractedRootDir(e),"complete")),await K(m.join(this.extractedRootDir(e),"quarterly"));}async has(e,r){await this.ensureDatasetDirs(e);let n=this.zipPath(e,r),s=this.extractedDir(e,r);return {zip:await b(n),extracted:await this.isExtractedReady(s)}}async downloadByFileId(e,r,n,s,o){await this.ensureDatasetDirs(e);let a=this.zipPath(e,r),i=!!o?.forceRefresh;if(!i&&await b(a)){let c=await this.safeStatSize(a);return this.logger?.info?.("Bulk ZIP already exists; skipping download",{dataset:e,source:r,zipPath:a,bytes:c,originalUrl:s}),{dataset:e,source:r,zipPath:a,bytes:c,downloaded:false}}if(!this.googleDriveApiKey)throw this.logger?.warn?.("Bulk ZIP download requested but API key missing",{dataset:e,source:r,zipPath:a,originalUrl:s,forceRefresh:i}),new h("BULK_DRIVE_API_KEY_REQUIRED",`Google Drive API key not provided; cannot download ${e}/${this.sourceKey(r)}.`,{dataset:e,source:r,expectedPath:a,zipPath:a,originalUrl:s,fileId:n,forceRefresh:i,envVar:q,option:"googleDriveApiKey",manualHint:"You can manually download the ZIP and place it at expectedPath to proceed without an API key."});this.logger?.info?.("Bulk ZIP download starting (Drive API)",{dataset:e,source:r,zipPath:a,fileId:n,originalUrl:s,forceRefresh:i});try{let c=await qr({fileId:n,apiKey:this.googleDriveApiKey,destinationPath:a,userAgent:this.userAgent,logger:this.logger,onProgress:o?.onProgress});return {dataset:e,source:r,zipPath:a,bytes:c.bytes,downloaded:!0,directUrl:s}}catch(c){throw this.logger?.error?.("Bulk ZIP download failed (Drive API)",{dataset:e,source:r,zipPath:a,fileId:n,originalUrl:s,err:c instanceof Error?c.message:String(c)}),new h("BULK_DRIVE_DOWNLOAD_FAILED",`Bulk download failed for ${e}/${this.sourceKey(r)}`,{dataset:e,source:r,zipPath:a,fileId:n,originalUrl:s,err:c})}}async extract(e,r,n){await this.ensureDatasetDirs(e);let s=this.zipPath(e,r),o=this.extractedDir(e,r);if(!await b(s))return this.logger?.warn?.("Bulk extract requested but ZIP missing",{dataset:e,source:r,zipPath:s}),{dataset:e,source:r,extractedDir:o,filesExtracted:0,extracted:false};if(await b(o)){let a=await b(this.markerOkPath(o)),i=await b(this.markerInProgressPath(o));if(a)return this.logger?.info?.("Bulk already extracted; skipping extraction",{dataset:e,source:r,extractedDir:o}),{dataset:e,source:r,extractedDir:o,filesExtracted:0,extracted:false};let c=await this.dirHasCsv(o,2);if(i||!c)this.logger?.warn?.("Bulk extracted dir exists but is incomplete; re-extracting",{dataset:e,source:r,extractedDir:o,inProgressMarker:i,hasCsv:c}),await O(o),await K(o);else return await this.writeMarkerOk(o,{dataset:e,source:r,note:"legacy-extraction-detected"}),this.logger?.info?.("Bulk extraction marker missing but CSVs found; marked as extracted",{dataset:e,source:r,extractedDir:o}),{dataset:e,source:r,extractedDir:o,filesExtracted:0,extracted:false}}else await K(o);await this.writeMarkerInProgress(o,{dataset:e,source:r}),this.logger?.info?.("Bulk ZIP extraction starting",{dataset:e,source:r,zipPath:s,extractedDir:o,concurrency:n?.concurrency});try{let a=await Fr(s,o,{onProgress:n?.onProgress,concurrency:n?.concurrency});return await O(this.markerInProgressPath(o)),await this.writeMarkerOk(o,{dataset:e,source:r,filesExtracted:a,at:new Date().toISOString()}),this.logger?.info?.("Bulk ZIP extraction complete",{dataset:e,source:r,extractedDir:o,filesExtracted:a}),{dataset:e,source:r,extractedDir:o,filesExtracted:a,extracted:!0}}catch(a){throw this.logger?.error?.("Bulk ZIP extraction failed",{dataset:e,source:r,zipPath:s,extractedDir:o,err:a instanceof Error?a.message:String(a)}),a}}async delete(e,r){await this.ensureDatasetDirs(e);let n=r.source,s=async o=>{let a=this.zipPath(e,o),i=this.extractedDir(e,o);(r.scope==="zips"||r.scope==="all")&&await O(a),(r.scope==="extracted"||r.scope==="all")&&await O(i);};if(n){await s(n);return}(r.scope==="zips"||r.scope==="all")&&(await O(this.zipsDir(e)),await K(this.zipsDir(e)),await K(m.join(this.zipsDir(e),"complete")),await K(m.join(this.zipsDir(e),"quarterly"))),(r.scope==="extracted"||r.scope==="all")&&(await O(this.extractedRootDir(e)),await K(this.extractedRootDir(e)),await K(m.join(this.extractedRootDir(e),"complete")),await K(m.join(this.extractedRootDir(e),"quarterly")));}async listDriveFolder(e){if(!this.googleDriveApiKey)throw new h("BULK_DRIVE_API_KEY_REQUIRED","Google Drive API key not provided; cannot list Drive folders.",{folderId:e,envVar:q,option:"googleDriveApiKey"});let r=this.driveFolderCache.get(e);if(r)return r;let n=Lr({folderId:e,apiKey:this.googleDriveApiKey,userAgent:this.userAgent,logger:this.logger});return this.driveFolderCache.set(e,n),n}async safeStatSize(e){try{return (await stat(e)).size}catch{return 0}}markerOkPath(e){return m.join(e,Qr)}markerInProgressPath(e){return m.join(e,zr)}async writeMarkerInProgress(e,r){let n=this.markerInProgressPath(e);await writeFile(n,JSON.stringify({at:new Date().toISOString(),meta:r}));}async writeMarkerOk(e,r){let n=this.markerOkPath(e);await writeFile(n,JSON.stringify({at:new Date().toISOString(),meta:r}));}async isExtractedReady(e){return await b(e)?await b(this.markerOkPath(e))?true:await b(this.markerInProgressPath(e))?false:this.dirHasCsv(e,2):false}async dirHasCsv(e,r){let n=[];try{n=await readdir(e);}catch{return false}for(let s of n){if(s===Qr||s===zr)continue;let o=m.join(e,s);if(s.toLowerCase().endsWith(".csv"))return true;if(r>0)try{let a=await readdir(o);for(let i of a)if(i.toLowerCase().endsWith(".csv"))return !0;if(r-1>0)for(let i of a){let c=m.join(o,i);try{let d=await readdir(c);for(let l of d)if(l.toLowerCase().endsWith(".csv"))return !0}catch{}}}catch{}}return false}};async function*F(t){let e=Gr.createReadStream(t),r=parse({columns:false,relax_column_count:true,trim:true,skip_empty_lines:true});e.on("error",s=>{r.destroy(s);});let n=e.pipe(r);for await(let s of n)yield s;}var Gn="1ptNqWYidLkhb2VAKuLCxmp2OXEfGO-AP",Cn="https://drive.google.com/file/d/1ptNqWYidLkhb2VAKuLCxmp2OXEfGO-AP/view?usp=sharing",H="15RSlNuW_h0kVM8or8McOGOMfHeBFvFGI",Y="https://drive.google.com/drive/folders/15RSlNuW_h0kVM8or8McOGOMfHeBFvFGI?usp=sharing",Q=class{constructor(e){this.base=e;}download(e,r){return e.type==="complete"?this.base.downloadByFileId("ohlcvt",e,Gn,Cn,r):this.downloadQuarter(e.quarter,r)}extract(e,r){return this.base.extract("ohlcvt",e,r)}has(e){return this.base.has("ohlcvt",e)}delete(e){return this.base.delete("ohlcvt",e)}query(e,r){let n=e.source??{type:"complete"};return this.queryFromExtracted(n,e,r)}async listPairs(e={type:"complete"}){let r=this.base.extractedDir("ohlcvt",e);if(!await b(r))return [];let n=await readdir(r),s=new Set;for(let o of n){if(!o.toLowerCase().endsWith(".csv"))continue;let a=o.slice(0,-4),i=a.lastIndexOf("_");if(i<=0)continue;let c=a.slice(i+1);/^\d+$/.test(c)&&s.add(a.slice(0,i));}return Array.from(s).sort()}async listIntervals(e,r={type:"complete"}){let n=this.base.extractedDir("ohlcvt",r);if(!await b(n))return [];let s=await readdir(n),o=new Set;for(let a of s){if(!a.toLowerCase().endsWith(".csv")||!a.startsWith(`${e}_`))continue;let i=a.slice(0,-4),c=i.lastIndexOf("_");if(c!==e.length)continue;let d=Number(i.slice(c+1));Number.isFinite(d)&&o.add(d);}return Array.from(o).sort((a,i)=>a-i).filter(Ln)}async listAvailableQuarters(){if(!this.base.hasGoogleDriveApiKey())throw new h("BULK_DRIVE_API_KEY_REQUIRED","Google Drive API key not provided; cannot list available quarters.",{envVar:this.base.driveApiKeyEnvVar(),option:"googleDriveApiKey"});let e=await this.base.listDriveFolder(H),r=/^Kraken_OHLCVT_Q([1-4])_(\d{4})\.zip$/i,n=new Set;for(let s of e){let o=s.name.match(r);if(!o)continue;let a=o[1],i=o[2];n.add(`${i}Q${a}`);}return Array.from(n).sort((s,o)=>{let a=Number(s.slice(0,4)),i=Number(o.slice(0,4));return a!==i?a-i:Number(s.slice(5))-Number(o.slice(5))})}async*queryFromExtracted(e,r,n){let s=this.base.extractedDir("ohlcvt",e);if(!await b(s)){this.base.logger?.warn?.("Bulk OHLCVT query requested but data not extracted",{source:e,extractedDir:s,pair:r.pair,interval:r.interval});return}let o=m.join(s,`${r.pair}_${r.interval}.csv`);if(!await b(o)){this.base.logger?.warn?.("Bulk OHLCVT CSV not found for pair/interval",{source:e,extractedDir:s,pair:r.pair,interval:r.interval,csvPath:o});return}let a=r.startTs,i=r.endTs,c=n?.limit,d=0;for await(let l of F(o)){if(l.length<7)continue;let u=Number(l[0]);if(!Number.isFinite(u)||a!==void 0&&u<a||i!==void 0&&u>=i)continue;let k=l[1],p=l[2],g=l[3],y=l[4],f=l[5],W=Number(l[6]);if(Number.isFinite(W)&&(yield {ts:u,open:k,high:p,low:g,close:y,volume:f,trades:W},d+=1,c!==void 0&&d>=c))return}}async downloadQuarter(e,r){let n={type:"quarterly",quarter:e};await this.base.ensureDatasetDirs("ohlcvt");let s=this.base.zipPath("ohlcvt",n),o=!!r?.forceRefresh;if(!o&&await b(s)){let l=await this.base.safeStatSize(s);return {dataset:"ohlcvt",source:n,zipPath:s,bytes:l,downloaded:false}}let a=`Kraken_OHLCVT_Q${Dn(e)}.zip`;if(!this.base.hasGoogleDriveApiKey())throw new h("BULK_DRIVE_API_KEY_REQUIRED",`Google Drive API key not provided; cannot download OHLCVT quarterly ZIP for ${e}.`,{dataset:"ohlcvt",quarter:e,wanted:a,expectedPath:s,folderId:H,folderUrl:Y,forceRefresh:o,envVar:this.base.driveApiKeyEnvVar(),option:"googleDriveApiKey",manualHint:"You can manually download the ZIP and place it at expectedPath to proceed without an API key."});let i=await this.base.listDriveFolder(H),c=i.find(l=>l.name===a)??i.find(l=>l.name.trim().toLowerCase()===a.trim().toLowerCase());if(!c){let l=i.slice(0,15).map(u=>u.name);throw this.base.logger?.warn?.("OHLCVT quarterly ZIP not found in Drive folder",{quarter:e,folder:Y,wanted:a,availableCount:i.length,availableSample:l}),new h("BULK_DRIVE_QUARTER_NOT_FOUND",`OHLCVT quarterly ZIP not found for ${e}`,{dataset:"ohlcvt",quarter:e,wanted:a,folderId:H,folderUrl:Y,availableCount:i.length,availableSample:l})}let d=`https://drive.google.com/file/d/${c.id}/view?usp=sharing`;return this.base.downloadByFileId("ohlcvt",n,c.id,d,r)}};function Dn(t){let e=t.match(/^(\d{4})Q([1-4])$/);return e?`${e[2]}_${e[1]}`:t}function Ln(t){return t===1||t===5||t===15||t===30||t===60||t===240||t===720||t===1440}var Fn="1nB0_Bv6oFQfqYxhhYkPSWXMWQRxmhRUZ",Hn="https://drive.google.com/file/d/1nB0_Bv6oFQfqYxhhYkPSWXMWQRxmhRUZ/view?usp=sharing",z="188O9xQjZTythjyLNes_5zfMEFaMbTT22",J="https://drive.google.com/drive/folders/188O9xQjZTythjyLNes_5zfMEFaMbTT22?usp=sharing",N=class{constructor(e){this.base=e;}download(e,r){return e.type==="complete"?this.base.downloadByFileId("trades",e,Fn,Hn,r):this.downloadQuarter(e.quarter,r)}extract(e,r){return this.base.extract("trades",e,r)}has(e){return this.base.has("trades",e)}delete(e){return this.base.delete("trades",e)}query(e,r){let n=e.source??{type:"complete"};return this.queryFromExtracted(n,e,r)}async listPairs(e={type:"complete"}){let r=this.base.extractedDir("trades",e);return await b(r)?(await readdir(r)).filter(s=>s.toLowerCase().endsWith(".csv")).map(s=>s.slice(0,-4)).sort():[]}async listAvailableQuarters(){if(!this.base.hasGoogleDriveApiKey())throw new h("BULK_DRIVE_API_KEY_REQUIRED","Google Drive API key not provided; cannot list available quarters.",{envVar:this.base.driveApiKeyEnvVar(),option:"googleDriveApiKey"});let e=await this.base.listDriveFolder(z),r=/^Kraken_(?:Trades|Trading_History)_Q([1-4])_(\d{4})\.zip$/i,n=new Set;for(let s of e){let o=s.name.match(r);if(!o)continue;let a=o[1],i=o[2];n.add(`${i}Q${a}`);}return Array.from(n).sort((s,o)=>{let a=Number(s.slice(0,4)),i=Number(o.slice(0,4));return a!==i?a-i:Number(s.slice(5))-Number(o.slice(5))})}async*queryFromExtracted(e,r,n){let s=this.base.extractedDir("trades",e);if(!await b(s)){this.base.logger?.warn?.("Bulk trades query requested but data not extracted",{source:e,extractedDir:s,pair:r.pair});return}let o=m.join(s,`${r.pair}.csv`);if(!await b(o)){this.base.logger?.warn?.("Bulk trades CSV not found for pair",{source:e,extractedDir:s,pair:r.pair,csvPath:o});return}let a=r.startTs,i=r.endTs,c=n?.limit,d=0;for await(let l of F(o)){if(l.length<3)continue;Number(l[0]);let k=Number(l[2]),p=Number.isFinite(k)&&k>1e9?2:0,g=p===2?0:1,y=p===2?1:2,f=Number(l[p]);if(!Number.isFinite(f)||a!==void 0&&f<a||i!==void 0&&f>=i)continue;let W=l[g],B=l[y];if(yield {ts:f,price:W,volume:B},d+=1,c!==void 0&&d>=c)return}}async downloadQuarter(e,r){let n={type:"quarterly",quarter:e};await this.base.ensureDatasetDirs("trades");let s=this.base.zipPath("trades",n),o=!!r?.forceRefresh;if(!o&&await b(s)){let u=await this.base.safeStatSize(s);return {dataset:"trades",source:n,zipPath:s,bytes:u,downloaded:false}}let a=Qn(e),i=[`Kraken_Trades_Q${a}.zip`,`Kraken_Trading_History_Q${a}.zip`];if(!this.base.hasGoogleDriveApiKey())throw new h("BULK_DRIVE_API_KEY_REQUIRED",`Google Drive API key not provided; cannot download trades quarterly ZIP for ${e}.`,{dataset:"trades",quarter:e,wantedCandidates:i,expectedPath:s,folderId:z,folderUrl:J,forceRefresh:o,envVar:this.base.driveApiKeyEnvVar(),option:"googleDriveApiKey",manualHint:"You can manually download the ZIP and place it at expectedPath to proceed without an API key."});let c=await this.base.listDriveFolder(z),d=c.find(u=>i.includes(u.name))??c.find(u=>i.some(k=>u.name.trim().toLowerCase()===k.trim().toLowerCase()));if(!d){let u=c.slice(0,15).map(k=>k.name);throw this.base.logger?.warn?.("Trades quarterly ZIP not found in Drive folder",{quarter:e,folder:J,wantedCandidates:i,availableCount:c.length,availableSample:u}),new h("BULK_DRIVE_QUARTER_NOT_FOUND",`Trades quarterly ZIP not found for ${e}`,{dataset:"trades",quarter:e,wantedCandidates:i,folderId:z,folderUrl:J,availableCount:c.length,availableSample:u})}let l=`https://drive.google.com/file/d/${d.id}/view?usp=sharing`;return this.base.downloadByFileId("trades",n,d.id,l,r)}};function Qn(t){let e=t.match(/^(\d{4})Q([1-4])$/);return e?`${e[2]}_${e[1]}`:t}var jr=class{trades;ohlcvt;base;constructor(e={}){this.base=new U(e),this.trades=new N(this.base),this.ohlcvt=new Q(this.base);}};
2
+ export{jr as KrakenBulkClient,_ as KrakenSpotAccountDataApi,I as KrakenSpotEarnApi,E as KrakenSpotFundingApi,S as KrakenSpotMarketDataApi,or as KrakenSpotRestClient,w as KrakenSpotSubaccountsApi,v as KrakenSpotTradingApi,M as KrakenSpotTransparencyApi,Mr as KrakenSpotWebsocketV2Client,R as KrakenWebsocketBase};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map