@@ -21,9 +21,16 @@ import { IPreparedTransaction } from './prepared-transaction';
21
21
import { EnrichedRequest , IConversionPaymentSettings } from './index' ;
22
22
import { checkRequestAndGetPathAndCurrency } from './any-to-erc20-proxy' ;
23
23
import { checkErc20Allowance , encodeApproveAnyErc20 } from './erc20' ;
24
- import { BATCH_PAYMENT_NETWORK_ID } from '@requestnetwork/types/dist/payment-types' ;
24
+ import { BATCH_PAYMENT_NETWORK_ID , RequestDetail } from '@requestnetwork/types/dist/payment-types' ;
25
25
import { IState } from 'types/dist/extension-types' ;
26
- import { CurrencyInput , isERC20Currency , isISO4217Currency } from '@requestnetwork/currency' ;
26
+ import {
27
+ CurrencyInput ,
28
+ isERC20Currency ,
29
+ isISO4217Currency ,
30
+ CurrencyManager ,
31
+ } from '@requestnetwork/currency' ;
32
+
33
+ const currencyManager = CurrencyManager . getDefault ( ) ;
27
34
28
35
/**
29
36
* Processes a transaction to pay a batch of requests with an ERC20 currency
@@ -33,6 +40,9 @@ import { CurrencyInput, isERC20Currency, isISO4217Currency } from '@requestnetwo
33
40
* @param enrichedRequests List of EnrichedRequests to pay
34
41
* @param version The version of the batch conversion proxy
35
42
* @param signerOrProvider The Web3 provider, or signer. Defaults to window.ethereum.
43
+ * @param skipFeeUSDLimit Setting the value to true skips the USD fee limit, and reduce gas consumption.
44
+ * It can be useful to set it to false if the total amount of the batch is important.
45
+ * Check the value of batchFeeAmountUSDLimit of the batch proxy deployed.
36
46
* @param overrides Optionally, override default transaction values, like gas.
37
47
* @dev We only implement batchPayments using two ERC20 functions:
38
48
* batchMultiERC20ConversionPayments, and batchMultiERC20Payments.
@@ -41,25 +51,34 @@ export async function payBatchConversionProxyRequest(
41
51
enrichedRequests : EnrichedRequest [ ] ,
42
52
version : string ,
43
53
signerOrProvider : providers . Provider | Signer = getProvider ( ) ,
54
+ skipFeeUSDLimit = true ,
44
55
overrides ?: ITransactionOverrides ,
45
56
) : Promise < ContractTransaction > {
46
- const { data, to, value } = prepareBatchConversionPaymentTransaction ( enrichedRequests , version ) ;
57
+ const { data, to, value } = prepareBatchConversionPaymentTransaction (
58
+ enrichedRequests ,
59
+ version ,
60
+ skipFeeUSDLimit ,
61
+ ) ;
47
62
const signer = getSigner ( signerOrProvider ) ;
48
63
return signer . sendTransaction ( { data, to, value, ...overrides } ) ;
49
64
}
50
65
51
66
/**
52
67
* Prepares a transaction to pay a batch of requests with an ERC20 currency
53
- * that is different from the request currency (eg. fiat)
54
- * it can be used with a Multisig contract.
68
+ * that can be different from the request currency (eg. fiat).
69
+ * It can be used with a Multisig contract.
55
70
* @param enrichedRequests List of EnrichedRequests to pay
56
71
* @param version The version of the batch conversion proxy
72
+ * @param skipFeeUSDLimit Setting the value to true skips the USD fee limit, and reduce gas consumption.
73
+ * It can be useful to set it to false if the total amount of the batch is important.
74
+ * Check the value of batchFeeAmountUSDLimit of the batch proxy deployed.
57
75
*/
58
76
export function prepareBatchConversionPaymentTransaction (
59
77
enrichedRequests : EnrichedRequest [ ] ,
60
78
version : string ,
79
+ skipFeeUSDLimit = true ,
61
80
) : IPreparedTransaction {
62
- const encodedTx = encodePayBatchConversionRequest ( enrichedRequests ) ;
81
+ const encodedTx = encodePayBatchConversionRequest ( enrichedRequests , skipFeeUSDLimit ) ;
63
82
const proxyAddress = getBatchConversionProxyAddress ( enrichedRequests [ 0 ] . request , version ) ;
64
83
return {
65
84
data : encodedTx ,
@@ -70,11 +89,17 @@ export function prepareBatchConversionPaymentTransaction(
70
89
71
90
/**
72
91
* Encodes a transaction to pay a batch of requests with an ERC20 currency
73
- * that is different from the request currency (eg. fiat)
92
+ * that can be different from the request currency (eg. fiat).
74
93
* It can be used with a Multisig contract.
75
94
* @param enrichedRequests List of EnrichedRequests to pay
95
+ * @param skipFeeUSDLimit Setting the value to true skips the USD fee limit, and reduce gas consumption.
96
+ * It can be useful to set it to false if the total amount of the batch is important.
97
+ * Check the value of batchFeeAmountUSDLimit of the batch proxy deployed.
76
98
*/
77
- export function encodePayBatchConversionRequest ( enrichedRequests : EnrichedRequest [ ] ) : string {
99
+ export function encodePayBatchConversionRequest (
100
+ enrichedRequests : EnrichedRequest [ ] ,
101
+ skipFeeUSDLimit = true ,
102
+ ) : string {
78
103
const { feeAddress } = getRequestPaymentValues ( enrichedRequests [ 0 ] . request ) ;
79
104
80
105
const firstNetwork = getPnAndNetwork ( enrichedRequests [ 0 ] . request ) [ 1 ] ;
@@ -101,7 +126,7 @@ export function encodePayBatchConversionRequest(enrichedRequests: EnrichedReques
101
126
) {
102
127
throw new Error ( `wrong request currencyInfo type` ) ;
103
128
}
104
- requestDetailsERC20Conversion . push ( getInputConversionDetail ( enrichedRequest ) ) ;
129
+ requestDetailsERC20Conversion . push ( getInputRequestDetailERC20Conversion ( enrichedRequest ) ) ;
105
130
} else if (
106
131
enrichedRequest . paymentNetworkId === BATCH_PAYMENT_NETWORK_ID . BATCH_MULTI_ERC20_PAYMENTS
107
132
) {
@@ -136,14 +161,24 @@ export function encodePayBatchConversionRequest(enrichedRequests: EnrichedReques
136
161
} ) ;
137
162
}
138
163
164
+ const pathsToUSD = getPathsToUSD (
165
+ [ ...requestDetailsERC20Conversion , ...requestDetailsERC20NoConversion ] ,
166
+ firstNetwork ,
167
+ skipFeeUSDLimit ,
168
+ ) ;
169
+
139
170
const proxyContract = BatchConversionPayments__factory . createInterface ( ) ;
140
171
return proxyContract . encodeFunctionData ( 'batchPayments' , [
141
172
metaDetails ,
142
- [ ] ,
173
+ skipFeeUSDLimit ? [ ] : pathsToUSD ,
143
174
feeAddress || constants . AddressZero ,
144
175
] ) ;
145
176
}
146
177
178
+ /**
179
+ * Get the ERC20 no conversion input requestDetail from a request, that can be used by the batch contract.
180
+ * @param request The request to pay.
181
+ */
147
182
function getInputRequestDetailERC20NoConversion (
148
183
request : ClientTypes . IRequestData ,
149
184
) : PaymentTypes . RequestDetail {
@@ -157,17 +192,19 @@ function getInputRequestDetailERC20NoConversion(
157
192
requestAmount : getAmountToPay ( request ) . toString ( ) ,
158
193
path : [ tokenAddress ] ,
159
194
paymentReference : `0x${ paymentReference } ` ,
160
- feeAmount : feeAmount || '0' ,
161
- maxToSpend : '' ,
162
- maxRateTimespan : '' ,
195
+ feeAmount : feeAmount ?. toString ( ) || '0' ,
196
+ maxToSpend : '0 ' ,
197
+ maxRateTimespan : '0 ' ,
163
198
} ;
164
199
}
165
200
166
201
/**
167
- * Get the conversion detail values from one enriched request
168
- * @param enrichedRequest The enrichedRequest to pay
202
+ * Get the ERC20 conversion input requestDetail from an enriched request, that can be used by the batch contract.
203
+ * @param enrichedRequest The enrichedRequest to pay.
169
204
*/
170
- function getInputConversionDetail ( enrichedRequest : EnrichedRequest ) : PaymentTypes . RequestDetail {
205
+ function getInputRequestDetailERC20Conversion (
206
+ enrichedRequest : EnrichedRequest ,
207
+ ) : PaymentTypes . RequestDetail {
171
208
const paymentSettings = enrichedRequest . paymentSettings ;
172
209
if ( ! paymentSettings ) throw Error ( 'the enrichedRequest has no paymentSettings' ) ;
173
210
@@ -198,7 +235,40 @@ function getInputConversionDetail(enrichedRequest: EnrichedRequest): PaymentType
198
235
}
199
236
200
237
/**
201
- *
238
+ * Get the list of conversion paths from tokens to the USD address through currencyManager.
239
+ * @param requestDetails List of ERC20 requests to pay.
240
+ * @param network The network targeted.
241
+ * @param skipFeeUSDLimit Setting the value to true skips the USD fee limit, and reduce gas consumption.
242
+ * It can be useful to set it to false if the total amount of the batch is important.
243
+ * Check the value of batchFeeAmountUSDLimit of the batch proxy deployed.
244
+ */
245
+ function getPathsToUSD (
246
+ requestDetails : RequestDetail [ ] ,
247
+ network : string ,
248
+ skipFeeUSDLimit : boolean ,
249
+ ) : string [ ] [ ] {
250
+ const pathsToUSD : Array < string > [ ] = [ ] ;
251
+ if ( ! skipFeeUSDLimit ) {
252
+ const USDCurrency = currencyManager . fromSymbol ( 'USD' ) ;
253
+ // token's addresses paid with the batch
254
+ const tokenAddresses : Array < string > = [ ] ;
255
+ for ( const requestDetail of requestDetails ) {
256
+ const tokenAddress = requestDetail . path [ requestDetail . path . length - 1 ] ;
257
+ // Check token to only unique paths token to USD.
258
+ if ( ! tokenAddresses . includes ( tokenAddress ) ) {
259
+ tokenAddresses . push ( tokenAddress ) ;
260
+ const tokenCurrency = currencyManager . fromAddress ( tokenAddress ) ;
261
+ const pathToUSD = currencyManager . getConversionPath ( tokenCurrency ! , USDCurrency ! , network ) ;
262
+ if ( pathToUSD ) {
263
+ pathsToUSD . push ( pathToUSD ) ;
264
+ }
265
+ }
266
+ }
267
+ }
268
+ return pathsToUSD ;
269
+ }
270
+
271
+ /**
202
272
* @param network The network targeted
203
273
* @param version The version of the batch conversion proxy
204
274
* @returns
0 commit comments