@@ -18,6 +18,10 @@ class PancakeSwapProvider extends SwapProvider {
18
18
private v3PancakeSubgraphClient : UrqlClient | undefined ;
19
19
private tokens : Map < Address , Token > ;
20
20
private quoteProvider : QuoteProvider ;
21
+ private _candidatePools : {
22
+ expirationTimestamp : Date ;
23
+ data : ReturnType < typeof SmartRouter . getV3CandidatePools > ;
24
+ } ;
21
25
22
26
constructor ( { subscriber } : { subscriber ?: ( msg : ConverterBotMessage ) => void } ) {
23
27
super ( { subscriber } ) ;
@@ -32,6 +36,10 @@ class PancakeSwapProvider extends SwapProvider {
32
36
this . tokens = new Map ( ) ;
33
37
this . chainName = config . network . name ;
34
38
this . liquidityProviderId = 1 ;
39
+ this . _candidatePools = {
40
+ expirationTimestamp : new Date ( ) ,
41
+ data : [ ] ,
42
+ } ;
35
43
}
36
44
37
45
/**
@@ -67,6 +75,31 @@ class PancakeSwapProvider extends SwapProvider {
67
75
throw new Error ( `Unable to fetch token details for ${ address } ` ) ;
68
76
}
69
77
78
+ /**
79
+ * Querying candidate pools can be a heavy operation so we cache it for 15 minutes
80
+ * @param swapFromToken
81
+ * @param swapToToken
82
+ */
83
+ getCandidatePools = async ( swapFromToken : Token , swapToToken : Token ) => {
84
+ const now = new Date ( ) ;
85
+ if ( ! this . _candidatePools . data . length || this . _candidatePools . expirationTimestamp < now ) {
86
+ const candidatePools = await SmartRouter . getV3CandidatePools ( {
87
+ onChainProvider : ( ) => this . publicClient ,
88
+ subgraphProvider : ( ) => this . v3PancakeSubgraphClient ,
89
+ currencyA : swapFromToken ,
90
+ currencyB : swapToToken ,
91
+ } ) ;
92
+
93
+ now . setMinutes ( 15 + new Date ( ) . getMinutes ( ) ) ;
94
+ this . _candidatePools . data = candidatePools ;
95
+ this . _candidatePools . expirationTimestamp = now ;
96
+
97
+ return candidatePools ;
98
+ }
99
+
100
+ return this . _candidatePools . data ;
101
+ } ;
102
+
70
103
async getBestTrade (
71
104
tokenConverter : Address ,
72
105
swapFrom : Address ,
@@ -76,6 +109,10 @@ class PancakeSwapProvider extends SwapProvider {
76
109
const swapFromToken = await this . getToken ( swapFrom ) ;
77
110
const swapToToken = await this . getToken ( swapTo ) ;
78
111
112
+ let trade ;
113
+ let error ;
114
+ let priceImpact ;
115
+
79
116
// [amount transferred out of converter, amount transferred in]
80
117
const { result : updatedAmountIn } = await this . publicClient . simulateContract ( {
81
118
address : tokenConverter ,
@@ -84,17 +121,9 @@ class PancakeSwapProvider extends SwapProvider {
84
121
args : [ amount , swapTo , swapFrom ] ,
85
122
} ) ;
86
123
87
- const candidatePools = await SmartRouter . getV3CandidatePools ( {
88
- onChainProvider : ( ) => this . publicClient ,
89
- subgraphProvider : ( ) => this . v3PancakeSubgraphClient ,
90
- currencyA : swapFromToken ,
91
- currencyB : swapToToken ,
92
- } ) ;
93
- let trade ;
94
- let error ;
95
- let priceImpact ;
96
-
97
124
try {
125
+ const candidatePools = await this . getCandidatePools ( swapFromToken , swapToToken ) ;
126
+
98
127
const response = await SmartRouter . getBestTrade (
99
128
CurrencyAmount . fromRawAmount ( swapToToken , updatedAmountIn [ 1 ] ) ,
100
129
swapFromToken ,
@@ -124,7 +153,13 @@ class PancakeSwapProvider extends SwapProvider {
124
153
}
125
154
priceImpact = SmartRouter . getPriceImpact ( response ) ;
126
155
} catch ( e ) {
127
- error = `Error getting best trade - ${ ( e as Error ) . message } ` ;
156
+ const message = ( e as Error ) . message ;
157
+ error = `Error getting best trade - ${ message } ` ;
158
+ // If we can't find a valid swap invalidate pool cache
159
+ if ( message === "Cannot find a valid swap route" ) {
160
+ this . _candidatePools . data = [ ] ;
161
+ this . _candidatePools . expirationTimestamp = new Date ( ) ;
162
+ }
128
163
throw new Error ( error ) ;
129
164
}
130
165
0 commit comments