Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@bancor/carbon-sdk

Package Overview
Dependencies
Maintainers
2
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bancor/carbon-sdk - npm Package Compare versions

Comparing version 0.0.97-DEV to 0.0.98-DEV

dist/index-e_tgjJqg.cjs

2

dist/chain-cache/ChainCache.d.ts

@@ -20,3 +20,3 @@ import { CacheEvents, TypedEventEmitter } from './types';

private _checkAndHandleCacheMiss;
clear(): void;
clear(silent?: boolean): void;
getStrategiesByPair(token0: string, token1: string): Promise<EncodedStrategy[] | undefined>;

@@ -23,0 +23,0 @@ getStrategyById(id: BigNumberish): EncodedStrategy | undefined;

@@ -1,1 +0,1 @@

import e from"events";import{fromPairKey as t,toPairKey as r,toDirectionKey as a,isOrderTradable as s}from"../utils/index.js";import{encodedStrategyStrToBN as i,encodedOrderStrToBN as d,encodedStrategyBNToStr as n,encodedOrderBNToStr as c}from"../../utils/serializers/index.js";import{Logger as o}from"../../common/logger/index.js";const h=new o("ChainCache.ts");class g extends e{_strategiesByPair={};_strategiesById={};_ordersByDirectedPair={};_latestBlockNumber=0;_latestTradesByPair={};_latestTradesByDirectedPair={};_blocksMetadata=[];_tradingFeePPMByPair={};_handleCacheMiss;static fromSerialized(e){try{const t=new g;return t._deserialize(e),t}catch(e){h.error("Failed to deserialize cache, returning clear cache",e)}return new g}_deserialize(e){const t=JSON.parse(e),{schemeVersion:r}=t;6===r?(this._strategiesByPair=Object.entries(t.strategiesByPair).reduce(((e,[t,r])=>(e[t]=r.map(i),e)),{}),this._strategiesById=Object.entries(t.strategiesById).reduce(((e,[t,r])=>(e[t]=i(r),e)),{}),this._ordersByDirectedPair=Object.entries(t.ordersByDirectedPair).reduce(((e,[t,r])=>(e[t]=Object.entries(r).reduce(((e,[t,r])=>(e[t]=d(r),e)),{}),e)),{}),this._tradingFeePPMByPair=t.tradingFeePPMByPair,this._latestBlockNumber=t.latestBlockNumber,this._latestTradesByPair=t.latestTradesByPair,this._latestTradesByDirectedPair=t.latestTradesByDirectedPair,this._blocksMetadata=t.blocksMetadata):h.log("Cache version mismatch, ignoring cache. Expected",6,"got",r,"This may be due to a breaking change in the cache format since it was last persisted.")}serialize(){const e={schemeVersion:6,strategiesByPair:Object.entries(this._strategiesByPair).reduce(((e,[t,r])=>(e[t]=r.map(n),e)),{}),strategiesById:Object.entries(this._strategiesById).reduce(((e,[t,r])=>(e[t]=n(r),e)),{}),ordersByDirectedPair:Object.entries(this._ordersByDirectedPair).reduce(((e,[t,r])=>(e[t]=Object.entries(r).reduce(((e,[t,r])=>(e[t]=c(r),e)),{}),e)),{}),tradingFeePPMByPair:this._tradingFeePPMByPair,latestBlockNumber:this._latestBlockNumber,latestTradesByPair:this._latestTradesByPair,latestTradesByDirectedPair:this._latestTradesByDirectedPair,blocksMetadata:this._blocksMetadata};return JSON.stringify(e)}setCacheMissHandler(e){this._handleCacheMiss=e}async _checkAndHandleCacheMiss(e,t){this._handleCacheMiss&&!this.hasCachedPair(e,t)&&(h.debug("Cache miss for pair",e,t),await this._handleCacheMiss(e,t),h.debug("Cache miss for pair",e,t,"resolved"))}clear(){const e=Object.keys(this._strategiesByPair).map(t);this._strategiesByPair={},this._strategiesById={},this._ordersByDirectedPair={},this._latestBlockNumber=0,this._latestTradesByPair={},this._latestTradesByDirectedPair={},this._blocksMetadata=[],this.emit("onPairDataChanged",e)}async getStrategiesByPair(e,t){await this._checkAndHandleCacheMiss(e,t);const a=r(e,t);return this._strategiesByPair[a]}getStrategyById(e){return this._strategiesById[e.toString()]}getCachedPairs(e=!0){return e?Object.entries(this._strategiesByPair).filter((([e,t])=>t.length>0)).map((([e,r])=>t(e))):Object.keys(this._strategiesByPair).map(t)}async getOrdersByPair(e,t,r=!1){await this._checkAndHandleCacheMiss(e,t);const i=a(e,t),d=this._ordersByDirectedPair[i]||{};return r?d:Object.fromEntries(Object.entries(d).filter((([e,t])=>s(t))))}hasCachedPair(e,t){const a=r(e,t);return!!this._strategiesByPair[a]}async getLatestTradeByPair(e,t){await this._checkAndHandleCacheMiss(e,t);const a=r(e,t);return this._latestTradesByPair[a]}async getLatestTradeByDirectedPair(e,t){await this._checkAndHandleCacheMiss(e,t);const r=a(e,t);return this._latestTradesByDirectedPair[r]}getLatestTrades(){return Object.values(this._latestTradesByPair)}getLatestBlockNumber(){return this._latestBlockNumber}async getTradingFeePPMByPair(e,t){await this._checkAndHandleCacheMiss(e,t);const a=r(e,t);return this._tradingFeePPMByPair[a]}get blocksMetadata(){return this._blocksMetadata}set blocksMetadata(e){this._blocksMetadata=e}addPair(e,a,s,i=!1){h.debug("Adding pair with",s.length," strategies to cache",e,a);const d=r(e,a);if(this._strategiesByPair[d])throw new Error(`Pair ${d} already cached`);this._strategiesByPair[d]=s,s.forEach((e=>{this._strategiesById[e.id.toString()]=e,this._addStrategyOrders(e)})),i||(h.debug("Emitting onPairAddedToCache",e,a),this.emit("onPairAddedToCache",t(d)))}addPairFees(e,t,a){h.debug("Adding trading fee to pair",e,t,"fee",a);const s=r(e,t);this._tradingFeePPMByPair[s]=a}applyBatchedUpdates(e,a,s,i,d,n){h.debug("Applying batched updates to cache",{latestBlockNumber:e,latestFeeUpdates:a,latestTrades:s,createdStrategies:i,updatedStrategies:d,deletedStrategies:n});const c=new Set;s.forEach((e=>{this._setLatestTrade(e),c.add(r(e.sourceToken,e.targetToken))})),i.forEach((e=>{this._addStrategy(e),c.add(r(e.token0,e.token1))})),d.forEach((e=>{this._updateStrategy(e),c.add(r(e.token0,e.token1))})),n.forEach((e=>{this._deleteStrategy(e),c.add(r(e.token0,e.token1))})),a.forEach((([e,t,a])=>{this._tradingFeePPMByPair[r(e,t)]=a})),this._setLatestBlockNumber(e),c.size>0&&(h.debug("Emitting onPairDataChanged",c),this.emit("onPairDataChanged",Array.from(c).map(t)))}_setLatestBlockNumber(e){this._latestBlockNumber=e}_setLatestTrade(e){if(!this.hasCachedPair(e.sourceToken,e.targetToken))throw new Error(`Pair ${r(e.sourceToken,e.targetToken)} is not cached, cannot set latest trade`);const t=r(e.sourceToken,e.targetToken);this._latestTradesByPair[t]=e;const s=a(e.sourceToken,e.targetToken);this._latestTradesByDirectedPair[s]=e}_addStrategyOrders(e){for(const t of[[e.token0,e.token1],[e.token1,e.token0]]){const r=a(t[0],t[1]),s=t[0]===e.token0?e.order1:e.order0,i=this._ordersByDirectedPair[r];i?i[e.id.toString()]=s:this._ordersByDirectedPair[r]={[e.id.toString()]:s}}}_removeStrategyOrders(e){for(const t of[[e.token0,e.token1],[e.token1,e.token0]]){const r=a(t[0],t[1]),s=this._ordersByDirectedPair[r];s&&(delete s[e.id.toString()],0===Object.keys(s).length&&delete this._ordersByDirectedPair.key)}}_addStrategy(e){if(!this.hasCachedPair(e.token0,e.token1))throw new Error(`Pair ${r(e.token0,e.token1)} is not cached, cannot add strategy`);const t=r(e.token0,e.token1);if(this._strategiesById[e.id.toString()])return void h.debug(`Strategy ${e.id} already cached, under the pair ${t} - skipping`);const a=this._strategiesByPair[t]||[];a.push(e),this._strategiesByPair[t]=a,this._strategiesById[e.id.toString()]=e,this._addStrategyOrders(e)}_updateStrategy(e){if(!this.hasCachedPair(e.token0,e.token1))throw new Error(`Pair ${r(e.token0,e.token1)} is not cached, cannot update strategy`);const t=r(e.token0,e.token1),a=(this._strategiesByPair[t]||[]).filter((t=>!t.id.eq(e.id)));a.push(e),this._strategiesByPair[t]=a,this._strategiesById[e.id.toString()]=e,this._removeStrategyOrders(e),this._addStrategyOrders(e)}_deleteStrategy(e){if(!this.hasCachedPair(e.token0,e.token1))throw new Error(`Pair ${r(e.token0,e.token1)} is not cached, cannot delete strategy`);const t=r(e.token0,e.token1);delete this._strategiesById[e.id.toString()];const a=(this._strategiesByPair[t]||[]).filter((t=>!t.id.eq(e.id)));this._strategiesByPair[t]=a,this._removeStrategyOrders(e)}}export{g as ChainCache};
import e from"events";import{fromPairKey as t,toPairKey as r,toDirectionKey as a,isOrderTradable as s}from"../utils/index.js";import{encodedStrategyStrToBN as i,encodedOrderStrToBN as d,encodedStrategyBNToStr as n,encodedOrderBNToStr as c}from"../../utils/serializers/index.js";import{Logger as o}from"../../common/logger/index.js";const h=new o("ChainCache.ts");class g extends e{_strategiesByPair={};_strategiesById={};_ordersByDirectedPair={};_latestBlockNumber=0;_latestTradesByPair={};_latestTradesByDirectedPair={};_blocksMetadata=[];_tradingFeePPMByPair={};_handleCacheMiss;static fromSerialized(e){try{const t=new g;return t._deserialize(e),t}catch(e){h.error("Failed to deserialize cache, returning clear cache",e)}return new g}_deserialize(e){const t=JSON.parse(e),{schemeVersion:r}=t;6===r?(this._strategiesByPair=Object.entries(t.strategiesByPair).reduce(((e,[t,r])=>(e[t]=r.map(i),e)),{}),this._strategiesById=Object.entries(t.strategiesById).reduce(((e,[t,r])=>(e[t]=i(r),e)),{}),this._ordersByDirectedPair=Object.entries(t.ordersByDirectedPair).reduce(((e,[t,r])=>(e[t]=Object.entries(r).reduce(((e,[t,r])=>(e[t]=d(r),e)),{}),e)),{}),this._tradingFeePPMByPair=t.tradingFeePPMByPair,this._latestBlockNumber=t.latestBlockNumber,this._latestTradesByPair=t.latestTradesByPair,this._latestTradesByDirectedPair=t.latestTradesByDirectedPair,this._blocksMetadata=t.blocksMetadata):h.log("Cache version mismatch, ignoring cache. Expected",6,"got",r,"This may be due to a breaking change in the cache format since it was last persisted.")}serialize(){const e={schemeVersion:6,strategiesByPair:Object.entries(this._strategiesByPair).reduce(((e,[t,r])=>(e[t]=r.map(n),e)),{}),strategiesById:Object.entries(this._strategiesById).reduce(((e,[t,r])=>(e[t]=n(r),e)),{}),ordersByDirectedPair:Object.entries(this._ordersByDirectedPair).reduce(((e,[t,r])=>(e[t]=Object.entries(r).reduce(((e,[t,r])=>(e[t]=c(r),e)),{}),e)),{}),tradingFeePPMByPair:this._tradingFeePPMByPair,latestBlockNumber:this._latestBlockNumber,latestTradesByPair:this._latestTradesByPair,latestTradesByDirectedPair:this._latestTradesByDirectedPair,blocksMetadata:this._blocksMetadata};return JSON.stringify(e)}setCacheMissHandler(e){this._handleCacheMiss=e}async _checkAndHandleCacheMiss(e,t){this._handleCacheMiss&&!this.hasCachedPair(e,t)&&(h.debug("Cache miss for pair",e,t),await this._handleCacheMiss(e,t),h.debug("Cache miss for pair",e,t,"resolved"))}clear(e=!1){const r=Object.keys(this._strategiesByPair).map(t);this._strategiesByPair={},this._strategiesById={},this._ordersByDirectedPair={},this._latestBlockNumber=0,this._latestTradesByPair={},this._latestTradesByDirectedPair={},this._blocksMetadata=[],e||this.emit("onPairDataChanged",r)}async getStrategiesByPair(e,t){await this._checkAndHandleCacheMiss(e,t);const a=r(e,t);return this._strategiesByPair[a]}getStrategyById(e){return this._strategiesById[e.toString()]}getCachedPairs(e=!0){return e?Object.entries(this._strategiesByPair).filter((([e,t])=>t.length>0)).map((([e,r])=>t(e))):Object.keys(this._strategiesByPair).map(t)}async getOrdersByPair(e,t,r=!1){await this._checkAndHandleCacheMiss(e,t);const i=a(e,t),d=this._ordersByDirectedPair[i]||{};return r?d:Object.fromEntries(Object.entries(d).filter((([e,t])=>s(t))))}hasCachedPair(e,t){const a=r(e,t);return!!this._strategiesByPair[a]}async getLatestTradeByPair(e,t){await this._checkAndHandleCacheMiss(e,t);const a=r(e,t);return this._latestTradesByPair[a]}async getLatestTradeByDirectedPair(e,t){await this._checkAndHandleCacheMiss(e,t);const r=a(e,t);return this._latestTradesByDirectedPair[r]}getLatestTrades(){return Object.values(this._latestTradesByPair)}getLatestBlockNumber(){return this._latestBlockNumber}async getTradingFeePPMByPair(e,t){await this._checkAndHandleCacheMiss(e,t);const a=r(e,t);return this._tradingFeePPMByPair[a]}get blocksMetadata(){return this._blocksMetadata}set blocksMetadata(e){this._blocksMetadata=e}addPair(e,a,s,i=!1){h.debug("Adding pair with",s.length," strategies to cache",e,a);const d=r(e,a);if(this._strategiesByPair[d])throw new Error(`Pair ${d} already cached`);this._strategiesByPair[d]=s,s.forEach((e=>{this._strategiesById[e.id.toString()]=e,this._addStrategyOrders(e)})),i||(h.debug("Emitting onPairAddedToCache",e,a),this.emit("onPairAddedToCache",t(d)))}addPairFees(e,t,a){h.debug("Adding trading fee to pair",e,t,"fee",a);const s=r(e,t);this._tradingFeePPMByPair[s]=a}applyBatchedUpdates(e,a,s,i,d,n){h.debug("Applying batched updates to cache",{latestBlockNumber:e,latestFeeUpdates:a,latestTrades:s,createdStrategies:i,updatedStrategies:d,deletedStrategies:n});const c=new Set;s.forEach((e=>{this._setLatestTrade(e),c.add(r(e.sourceToken,e.targetToken))})),i.forEach((e=>{this._addStrategy(e),c.add(r(e.token0,e.token1))})),d.forEach((e=>{this._updateStrategy(e),c.add(r(e.token0,e.token1))})),n.forEach((e=>{this._deleteStrategy(e),c.add(r(e.token0,e.token1))})),a.forEach((([e,t,a])=>{this._tradingFeePPMByPair[r(e,t)]=a})),this._setLatestBlockNumber(e),c.size>0&&(h.debug("Emitting onPairDataChanged",c),this.emit("onPairDataChanged",Array.from(c).map(t)))}_setLatestBlockNumber(e){this._latestBlockNumber=e}_setLatestTrade(e){if(!this.hasCachedPair(e.sourceToken,e.targetToken))throw new Error(`Pair ${r(e.sourceToken,e.targetToken)} is not cached, cannot set latest trade`);const t=r(e.sourceToken,e.targetToken);this._latestTradesByPair[t]=e;const s=a(e.sourceToken,e.targetToken);this._latestTradesByDirectedPair[s]=e}_addStrategyOrders(e){for(const t of[[e.token0,e.token1],[e.token1,e.token0]]){const r=a(t[0],t[1]),s=t[0]===e.token0?e.order1:e.order0,i=this._ordersByDirectedPair[r];i?i[e.id.toString()]=s:this._ordersByDirectedPair[r]={[e.id.toString()]:s}}}_removeStrategyOrders(e){for(const t of[[e.token0,e.token1],[e.token1,e.token0]]){const r=a(t[0],t[1]),s=this._ordersByDirectedPair[r];s&&(delete s[e.id.toString()],0===Object.keys(s).length&&delete this._ordersByDirectedPair.key)}}_addStrategy(e){if(!this.hasCachedPair(e.token0,e.token1))throw new Error(`Pair ${r(e.token0,e.token1)} is not cached, cannot add strategy`);const t=r(e.token0,e.token1);if(this._strategiesById[e.id.toString()])return void h.debug(`Strategy ${e.id} already cached, under the pair ${t} - skipping`);const a=this._strategiesByPair[t]||[];a.push(e),this._strategiesByPair[t]=a,this._strategiesById[e.id.toString()]=e,this._addStrategyOrders(e)}_updateStrategy(e){if(!this.hasCachedPair(e.token0,e.token1))throw new Error(`Pair ${r(e.token0,e.token1)} is not cached, cannot update strategy`);const t=r(e.token0,e.token1),a=(this._strategiesByPair[t]||[]).filter((t=>!t.id.eq(e.id)));a.push(e),this._strategiesByPair[t]=a,this._strategiesById[e.id.toString()]=e,this._removeStrategyOrders(e),this._addStrategyOrders(e)}_deleteStrategy(e){if(!this.hasCachedPair(e.token0,e.token1))throw new Error(`Pair ${r(e.token0,e.token1)} is not cached, cannot delete strategy`);const t=r(e.token0,e.token1);delete this._strategiesById[e.id.toString()];const a=(this._strategiesByPair[t]||[]).filter((t=>!t.id.eq(e.id)));this._strategiesByPair[t]=a,this._removeStrategyOrders(e)}}export{g as ChainCache};

@@ -11,3 +11,4 @@ import { ChainCache } from './ChainCache';

private _initialSyncDone;
constructor(fetcher: Fetcher, chainCache: ChainCache);
private _maxBlockAge?;
constructor(fetcher: Fetcher, chainCache: ChainCache, maxBlockAge?: number);
startDataSync(): Promise<void>;

@@ -14,0 +15,0 @@ private _updatePairsFromChain;

@@ -1,1 +0,1 @@

import{findAndRemoveLeading as e,toPairKey as t}from"../utils/index.js";import{Logger as a}from"../../common/logger/index.js";const s=new a("ChainSync.ts");class i{_fetcher;_chainCache;_syncCalled=!1;_slowPollPairs=!1;_pairs=[];_lastFetch=Date.now();_initialSyncDone=!1;constructor(e,t){this._fetcher=e,this._chainCache=t}async startDataSync(){if(s.debug("startDataSync called"),this._syncCalled)throw new Error("ChainSync.startDataSync() can only be called once");this._syncCalled=!0;const e=await this._fetcher.getBlockNumber();0===this._chainCache.getLatestBlockNumber()&&(s.debug("startDataSync - cache is new",arguments),this._chainCache.applyBatchedUpdates(e,[],[],[],[],[])),await this._updatePairsFromChain(),await Promise.all([this._populateFeesData(this._pairs),this._populatePairsData(),this._syncEvents()])}async _updatePairsFromChain(){s.debug("_updatePairsFromChain fetches pairs"),this._pairs=[...await this._fetcher.pairs()],s.debug("_updatePairsFromChain fetched pairs",this._pairs),this._lastFetch=Date.now(),0===this._pairs.length&&s.error("_updatePairsFromChain fetched no pairs - this indicates a problem")}async _populateFeesData(e,t=!1){if(s.debug("populateFeesData called"),0===e.length)return void s.error("populateFeesData called with no pairs - skipping");const a=t?e:e.filter((e=>!this._chainCache.hasCachedPair(e[0],e[1])));if(0===a.length)return;const i=await this._fetcher.pairsTradingFeePPM(a);s.debug("populateFeesData fetched fee updates",i),i.forEach((e=>{this._chainCache.addPairFees(e[0],e[1],e[2])}))}async _populatePairsData(){s.debug("_populatePairsData called"),this._slowPollPairs=!1;const t=async()=>{try{if(0===this._pairs.length){if(this._slowPollPairs&&Date.now()-this._lastFetch<6e4)return void setTimeout(t,1e3);await this._updatePairsFromChain()}const a=e(this._pairs,(e=>!this._chainCache.hasCachedPair(e[0],e[1])));a?(s.debug("_populatePairsData adds pair to cache",a),await this.syncPairData(a[0],a[1],!this._initialSyncDone),setTimeout(t,1)):(s.debug("_populatePairsData handled all pairs and goes to slow poll mode"),this._slowPollPairs=!0,this._initialSyncDone=!0,setTimeout(t,1e3))}catch(e){s.error("Error while syncing pairs data",e),setTimeout(t,6e4)}};setTimeout(t,1)}async syncPairData(e,t,a=!1){if(!this._syncCalled)throw new Error("ChainSync.startDataSync() must be called before syncPairData()");const s=await this._fetcher.strategiesByPair(e,t);this._chainCache.hasCachedPair(e,t)||this._chainCache.addPair(e,t,s,a)}_getBlockChunks(e,t,a){const s=[];for(let i=e;i<=t;i+=a){const e=i,h=Math.min(i+a-1,t);s.push([e,h])}return s}async _syncEvents(){s.debug("_syncEvents called");const e=async()=>{try{const a=this._chainCache.getLatestBlockNumber(),i=await this._fetcher.getBlockNumber();if(i>a){if(await this._detectReorg(i))return s.debug("_syncEvents detected reorg - resetting"),this._chainCache.clear(),this._chainCache.applyBatchedUpdates(i,[],[],[],[],[]),this._resetPairsFetching(),void setTimeout(e,1);const h=new Set(this._chainCache.getCachedPairs(!1).map((e=>t(e[0],e[1]))));s.debug("_syncEvents fetches events",a+1,i);const n=this._getBlockChunks(a+1,i,1e3);s.debug("_syncEvents block chunks",n);const r=[],c=[],o=[],l=[],d=[],u=[];for(const e of n){s.debug("_syncEvents fetches events for chunk",e);const t=await this._fetcher.getLatestStrategyCreatedStrategies(e[0],e[1]),a=await this._fetcher.getLatestStrategyUpdatedStrategies(e[0],e[1]),i=await this._fetcher.getLatestStrategyDeletedStrategies(e[0],e[1]),h=await this._fetcher.getLatestTokensTradedTrades(e[0],e[1]),_=await this._fetcher.getLatestPairTradingFeeUpdates(e[0],e[1]),p=await this._fetcher.getLatestTradingFeeUpdates(e[0],e[1]);r.push(t),c.push(a),o.push(i),l.push(h),d.push(_),u.push(p),s.debug("_syncEvents fetched the following events for chunks",n,{createdStrategiesChunk:t,updatedStrategiesChunk:a,deletedStrategiesChunk:i,tradesChunk:h,feeUpdatesChunk:_,defaultFeeUpdatesChunk:p})}const _=r.flat(),p=c.flat(),g=o.flat(),f=l.flat(),y=d.flat(),w=u.flat().length>0;s.debug("_syncEvents fetched events",_,p,g,f,y,w);const C=[];for(const e of _)this._chainCache.hasCachedPair(e.token0,e.token1)||C.push([e.token0,e.token1]);this._chainCache.applyBatchedUpdates(i,y,f.filter((e=>h.has(t(e.sourceToken,e.targetToken)))),_.filter((e=>h.has(t(e.token0,e.token1)))),p.filter((e=>h.has(t(e.token0,e.token1)))),g.filter((e=>h.has(t(e.token0,e.token1))))),w&&(s.debug("_syncEvents noticed at least one default fee update - refetching pair fees for all pairs"),await this._populateFeesData([...await this._fetcher.pairs()],!0)),C.length>0&&(s.debug("_syncEvents noticed at least one new pair created - setting slow poll mode to false"),this._slowPollPairs=!1,s.debug("_syncEvents fetching fees for the new pairs"),await this._populateFeesData(C,!0))}}catch(e){s.error("Error syncing events:",e)}setTimeout(e,1e3)};setTimeout(e,1)}_resetPairsFetching(){this._pairs=[],this._slowPollPairs=!1,this._initialSyncDone=!1}async _detectReorg(e){s.debug("_detectReorg called");const t=this._chainCache.blocksMetadata,a={};for(const i of t){const{number:t,hash:h}=i;if(t>e)return s.log("reorg detected for block number",t,"larger than current block",e,"with hash",h),!0;const n=(await this._fetcher.getBlock(t)).hash;if(h!==n)return s.log("reorg detected for block number",t,"old hash",h,"new hash",n),!0;a[t]=i}s.debug("_detectReorg no reorg detected, updating blocks metadata");const i=[];for(let t=0;t<3;t++)a[e-t]?i.push(a[e-t]):i.push(await this._fetcher.getBlock(e-t));return this._chainCache.blocksMetadata=i,s.debug("_detectReorg updated blocks metadata"),!1}}export{i as ChainSync};
import{findAndRemoveLeading as e,toPairKey as t}from"../utils/index.js";import{Logger as a}from"../../common/logger/index.js";const s=new a("ChainSync.ts");class i{_fetcher;_chainCache;_syncCalled=!1;_slowPollPairs=!1;_pairs=[];_lastFetch=Date.now();_initialSyncDone=!1;_maxBlockAge;constructor(e,t,a){this._fetcher=e,this._chainCache=t,this._maxBlockAge=a}async startDataSync(){if(s.debug("startDataSync called"),this._syncCalled)throw new Error("ChainSync.startDataSync() can only be called once");this._syncCalled=!0;const e=await this._fetcher.getBlockNumber(),t=this._chainCache.getLatestBlockNumber();0===t?(s.debug("startDataSync - cache is new",arguments),this._chainCache.applyBatchedUpdates(e,[],[],[],[],[])):void 0!==this._maxBlockAge&&e-t>this._maxBlockAge&&(s.debug(`startDataSync - cache is too old: current block ${e}, cache block ${t}`,arguments),this._chainCache.clear(!0),this._chainCache.applyBatchedUpdates(e,[],[],[],[],[])),await this._updatePairsFromChain(),await Promise.all([this._populateFeesData(this._pairs),this._populatePairsData(),this._syncEvents()])}async _updatePairsFromChain(){s.debug("_updatePairsFromChain fetches pairs"),this._pairs=[...await this._fetcher.pairs()],s.debug("_updatePairsFromChain fetched pairs",this._pairs),this._lastFetch=Date.now(),0===this._pairs.length&&s.error("_updatePairsFromChain fetched no pairs - this indicates a problem")}async _populateFeesData(e,t=!1){if(s.debug("populateFeesData called"),0===e.length)return void s.error("populateFeesData called with no pairs - skipping");const a=t?e:e.filter((e=>!this._chainCache.hasCachedPair(e[0],e[1])));if(0===a.length)return;const i=await this._fetcher.pairsTradingFeePPM(a);s.debug("populateFeesData fetched fee updates",i),i.forEach((e=>{this._chainCache.addPairFees(e[0],e[1],e[2])}))}async _populatePairsData(){s.debug("_populatePairsData called"),this._slowPollPairs=!1;const t=async()=>{try{if(0===this._pairs.length){if(this._slowPollPairs&&Date.now()-this._lastFetch<6e4)return void setTimeout(t,1e3);await this._updatePairsFromChain()}const a=e(this._pairs,(e=>!this._chainCache.hasCachedPair(e[0],e[1])));a?(s.debug("_populatePairsData adds pair to cache",a),await this.syncPairData(a[0],a[1],!this._initialSyncDone),setTimeout(t,1)):(s.debug("_populatePairsData handled all pairs and goes to slow poll mode"),this._slowPollPairs=!0,this._initialSyncDone=!0,setTimeout(t,1e3))}catch(e){s.error("Error while syncing pairs data",e),setTimeout(t,6e4)}};setTimeout(t,1)}async syncPairData(e,t,a=!1){if(!this._syncCalled)throw new Error("ChainSync.startDataSync() must be called before syncPairData()");const s=await this._fetcher.strategiesByPair(e,t);this._chainCache.hasCachedPair(e,t)||this._chainCache.addPair(e,t,s,a)}_getBlockChunks(e,t,a){const s=[];for(let i=e;i<=t;i+=a){const e=i,h=Math.min(i+a-1,t);s.push([e,h])}return s}async _syncEvents(){s.debug("_syncEvents called");const e=async()=>{try{const a=this._chainCache.getLatestBlockNumber(),i=await this._fetcher.getBlockNumber();if(i>a){if(await this._detectReorg(i))return s.debug("_syncEvents detected reorg - resetting"),this._chainCache.clear(),this._chainCache.applyBatchedUpdates(i,[],[],[],[],[]),this._resetPairsFetching(),void setTimeout(e,1);const h=new Set(this._chainCache.getCachedPairs(!1).map((e=>t(e[0],e[1]))));s.debug("_syncEvents fetches events",a+1,i);const c=this._getBlockChunks(a+1,i,1e3);s.debug("_syncEvents block chunks",c);const n=[],r=[],o=[],l=[],d=[],_=[];for(const e of c){s.debug("_syncEvents fetches events for chunk",e);const t=await this._fetcher.getLatestStrategyCreatedStrategies(e[0],e[1]),a=await this._fetcher.getLatestStrategyUpdatedStrategies(e[0],e[1]),i=await this._fetcher.getLatestStrategyDeletedStrategies(e[0],e[1]),h=await this._fetcher.getLatestTokensTradedTrades(e[0],e[1]),u=await this._fetcher.getLatestPairTradingFeeUpdates(e[0],e[1]),p=await this._fetcher.getLatestTradingFeeUpdates(e[0],e[1]);n.push(t),r.push(a),o.push(i),l.push(h),d.push(u),_.push(p),s.debug("_syncEvents fetched the following events for chunks",c,{createdStrategiesChunk:t,updatedStrategiesChunk:a,deletedStrategiesChunk:i,tradesChunk:h,feeUpdatesChunk:u,defaultFeeUpdatesChunk:p})}const u=n.flat(),p=r.flat(),g=o.flat(),f=l.flat(),y=d.flat(),k=_.flat().length>0;s.debug("_syncEvents fetched events",u,p,g,f,y,k);const w=[];for(const e of u)this._chainCache.hasCachedPair(e.token0,e.token1)||w.push([e.token0,e.token1]);this._chainCache.applyBatchedUpdates(i,y,f.filter((e=>h.has(t(e.sourceToken,e.targetToken)))),u.filter((e=>h.has(t(e.token0,e.token1)))),p.filter((e=>h.has(t(e.token0,e.token1)))),g.filter((e=>h.has(t(e.token0,e.token1))))),k&&(s.debug("_syncEvents noticed at least one default fee update - refetching pair fees for all pairs"),await this._populateFeesData([...await this._fetcher.pairs()],!0)),w.length>0&&(s.debug("_syncEvents noticed at least one new pair created - setting slow poll mode to false"),this._slowPollPairs=!1,s.debug("_syncEvents fetching fees for the new pairs"),await this._populateFeesData(w,!0))}}catch(e){s.error("Error syncing events:",e)}setTimeout(e,1e3)};setTimeout(e,1)}_resetPairsFetching(){this._pairs=[],this._slowPollPairs=!1,this._initialSyncDone=!1}async _detectReorg(e){s.debug("_detectReorg called");const t=this._chainCache.blocksMetadata,a={};for(const i of t){const{number:t,hash:h}=i;if(t>e)return s.log("reorg detected for block number",t,"larger than current block",e,"with hash",h),!0;const c=(await this._fetcher.getBlock(t)).hash;if(h!==c)return s.log("reorg detected for block number",t,"old hash",h,"new hash",c),!0;a[t]=i}s.debug("_detectReorg no reorg detected, updating blocks metadata");const i=[];for(let t=0;t<3;t++)a[e-t]?i.push(a[e-t]):i.push(await this._fetcher.getBlock(e-t));return this._chainCache.blocksMetadata=i,s.debug("_detectReorg updated blocks metadata"),!1}}export{i as ChainSync};

@@ -18,3 +18,3 @@ import { Fetcher } from '../common/types';

*/
export declare const initSyncedCache: (fetcher: Fetcher, cachedData?: string) => {
export declare const initSyncedCache: (fetcher: Fetcher, cachedData?: string, maxBlockAge?: number) => {
cache: ChainCache;

@@ -21,0 +21,0 @@ startDataSync: () => Promise<void>;

@@ -1,1 +0,1 @@

import{ChainCache as a}from"./ChainCache/index.js";import{ChainSync as n}from"./ChainSync/index.js";const t=(t,e)=>{let r;e&&(r=a.fromSerialized(e)),r||(r=new a);const i=new n(t,r);return r.setCacheMissHandler(i.syncPairData.bind(i)),{cache:r,startDataSync:i.startDataSync.bind(i)}};export{a as ChainCache,n as ChainSync,t as initSyncedCache};
import{ChainCache as a}from"./ChainCache/index.js";import{ChainSync as n}from"./ChainSync/index.js";const t=(t,e,r)=>{let i;e&&(i=a.fromSerialized(e)),i||(i=new a);const c=new n(t,i,r);return i.setCacheMissHandler(c.syncPairData.bind(c)),{cache:i,startDataSync:c.startDataSync.bind(c)}};export{a as ChainCache,n as ChainSync,t as initSyncedCache};

@@ -5,3 +5,3 @@ {

"source": "src/index.ts",
"version": "0.0.97-DEV",
"version": "0.0.98-DEV",
"description": "The SDK is a READ-ONLY tool, intended to facilitate working with Carbon contracts. It's a convenient wrapper around our matching algorithm, allowing programs and users get a ready to use transaction data that will allow them to manage strategies and fulfill trades",

@@ -8,0 +8,0 @@ "main": "dist/index.cjs",

@@ -45,2 +45,3 @@ # Carbon SDK

let isInitializing = false;
const MAX_BLOCK_AGE = 2000; // past this many blocks, the SDK won't attempt to catch up by processing events and instead call the contracts for strategy info.

@@ -60,3 +61,3 @@ const init = async (

api = new ContractsApi(provider, config);
const { cache, startDataSync } = initSyncedCache(api.reader, cachedData);
const { cache, startDataSync } = initSyncedCache(api.reader, cachedData, MAX_BLOCK_AGE);
sdkCache = cache;

@@ -85,18 +86,19 @@ carbonSDK = new Toolkit(

### 1. The SDK Logger supports 3 verbosity levels:
- `0` (default) only prints errors and important logs.
- `1` (debug) prints highly verbose logs.
- `2` (debug readable) is same as `1` but also converts any BigNumber to an easy to read string (impacting performance).
To use it in Node, set the environment variable `CARBON_DEFI_SDK_VERBOSITY` to the desired level.
To use it from a browser app do, before importing the SDK:
```js
window.CARBON_DEFI_SDK_VERBOSITY = 2;
```
- `0` (default) only prints errors and important logs.
- `1` (debug) prints highly verbose logs.
- `2` (debug readable) is same as `1` but also converts any BigNumber to an easy to read string (impacting performance).
To use it in Node, set the environment variable `CARBON_DEFI_SDK_VERBOSITY` to the desired level.
To use it from a browser app do, before importing the SDK:
```js
window.CARBON_DEFI_SDK_VERBOSITY = 2;
```
### 2. For usage with contracts version < 5, without the enhanced range for trade by source:
```js
window.LEGACY_TRADE_BY_SOURCE_RANGE = true;
```
```js
window.LEGACY_TRADE_BY_SOURCE_RANGE = true;
```

@@ -103,0 +105,0 @@ ## Authors

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc