@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/README.md +224 -117
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +333 -1
- package/dist/index.d.ts +333 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +23 -6
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var crypto=require('crypto'),ws=require('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=crypto.createHash("sha256").update(s+a).digest(),l=Buffer.from(this.apiSecret,"base64"),d=crypto.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=crypto.createHash("sha256").update(r+n).digest(),a=crypto.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 ws.WebSocket<"u"?ws.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
|
-
exports.KrakenSpotAccountDataApi=
|
|
1
|
+
'use strict';var crypto=require('crypto'),ws=require('ws'),vn=require('os'),m=require('path'),promises=require('fs/promises'),Gr=require('fs'),promises$1=require('stream/promises'),googleapis=require('googleapis'),Wn=require('yauzl'),csvParse=require('csv-parse');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var vn__default=/*#__PURE__*/_interopDefault(vn);var m__default=/*#__PURE__*/_interopDefault(m);var Gr__default=/*#__PURE__*/_interopDefault(Gr);var Wn__default=/*#__PURE__*/_interopDefault(Wn);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=crypto.createHash("sha256").update(s+a).digest(),c=Buffer.from(this.apiSecret,"base64"),d=crypto.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=crypto.createHash("sha256").update(r+n).digest(),a=crypto.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 ws.WebSocket<"u"?ws.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__default.default.promises.mkdir(t,{recursive:true});}async function b(t){try{return await promises.stat(t),!0}catch{return false}}async function O(t){try{await Gr__default.default.promises.rm(t,{recursive:!0,force:!0});}catch{}}function Dr(){return googleapis.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__default.default.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 promises$1.pipeline(k,Gr__default.default.createWriteStream(d)),await promises.rm(n,{force:!0}).catch(()=>{}),await promises.rename(d,n),a?.({downloadedBytes:l,totalBytes:c}),{bytes:l,totalBytes:c}}catch(u){try{await promises.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__default.default.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__default.default.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__default.default.createWriteStream(r);try{await promises$1.pipeline(a,i),n();}catch(c){try{i.destroy();}catch{}try{Gr__default.default.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__default.default.join(t,r),s=m__default.default.resolve(t)+m__default.default.sep,o=m__default.default.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__default.default.join(vn__default.default.homedir(),".lynx-crypto","bulk");this.storageDir=m__default.default.isAbsolute(r)?r:m__default.default.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__default.default.join(this.storageDir,e)}zipsDir(e){return m__default.default.join(this.datasetDir(e),"zips")}extractedRootDir(e){return m__default.default.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__default.default.join(this.zipsDir(e),this.zipBucket(r))}extractedBucketDir(e,r){return r.type==="complete"?m__default.default.join(this.extractedRootDir(e),"complete"):m__default.default.join(this.extractedRootDir(e),"quarterly",r.quarter)}zipPath(e,r){return m__default.default.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__default.default.join(this.zipsDir(e),"complete")),await K(m__default.default.join(this.zipsDir(e),"quarterly")),await K(this.extractedRootDir(e)),await K(m__default.default.join(this.extractedRootDir(e),"complete")),await K(m__default.default.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__default.default.join(this.zipsDir(e),"complete")),await K(m__default.default.join(this.zipsDir(e),"quarterly"))),(r.scope==="extracted"||r.scope==="all")&&(await O(this.extractedRootDir(e)),await K(this.extractedRootDir(e)),await K(m__default.default.join(this.extractedRootDir(e),"complete")),await K(m__default.default.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 promises.stat(e)).size}catch{return 0}}markerOkPath(e){return m__default.default.join(e,Qr)}markerInProgressPath(e){return m__default.default.join(e,zr)}async writeMarkerInProgress(e,r){let n=this.markerInProgressPath(e);await promises.writeFile(n,JSON.stringify({at:new Date().toISOString(),meta:r}));}async writeMarkerOk(e,r){let n=this.markerOkPath(e);await promises.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 promises.readdir(e);}catch{return false}for(let s of n){if(s===Qr||s===zr)continue;let o=m__default.default.join(e,s);if(s.toLowerCase().endsWith(".csv"))return true;if(r>0)try{let a=await promises.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__default.default.join(o,i);try{let d=await promises.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__default.default.createReadStream(t),r=csvParse.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 promises.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 promises.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__default.default.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 promises.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__default.default.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
|
+
exports.KrakenBulkClient=jr;exports.KrakenSpotAccountDataApi=_;exports.KrakenSpotEarnApi=I;exports.KrakenSpotFundingApi=E;exports.KrakenSpotMarketDataApi=S;exports.KrakenSpotRestClient=or;exports.KrakenSpotSubaccountsApi=w;exports.KrakenSpotTradingApi=v;exports.KrakenSpotTransparencyApi=M;exports.KrakenSpotWebsocketV2Client=Mr;exports.KrakenWebsocketBase=R;//# sourceMappingURL=index.cjs.map
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|