1
1
import IArbitrator from '@kleros/erc-792/build/contracts/IArbitrator.json' ;
2
2
import Linguo from '@kleros/linguo-contracts/artifacts/contracts/0.7.x/Linguo.sol/Linguo.json' ;
3
- import { subtract } from '~/adapters/big-number' ;
4
3
import { combination } from '~/adapters/js-combinatorics' ;
5
4
import { withProvider } from '~/app/archon' ;
6
5
import {
9
8
compose ,
10
9
filter ,
11
10
flatten ,
12
- indexBy ,
13
11
map ,
14
12
mapValues ,
15
13
omit ,
@@ -32,7 +30,7 @@ export default async function createApiFacade({ web3, chainId }) {
32
30
createApiInstance ( {
33
31
web3,
34
32
archon,
35
- contracts : await getLinguoContracts ( { web3, chainId, address, deployment : Linguo } ) ,
33
+ contracts : await getContracts ( { web3, chainId, address, deployment : Linguo } ) ,
36
34
} )
37
35
) ,
38
36
addressesByLanguageGroupPair
@@ -134,7 +132,7 @@ export default async function createApiFacade({ web3, chainId }) {
134
132
135
133
const addresses = uniq ( [
136
134
...hintedAddresses ,
137
- ...( await getContractAddressesForRequester ( { web3 , chainId , account, apiInstancesByAddress } ) ) ,
135
+ ...( await getContractAddressesForRequester ( { account, apiInstancesByAddress } ) ) ,
138
136
] ) ;
139
137
140
138
const instances = Object . values ( pick ( addresses , apiInstancesByAddress ) ) ;
@@ -168,22 +166,28 @@ export default async function createApiFacade({ web3, chainId }) {
168
166
...rest ,
169
167
] ;
170
168
171
- const actualApi = apiInstancesByAddress [ address ] ;
172
- if ( actualApi ) {
173
- return actualApi [ target . name ] . apply ( actualApi , actualArgs ) ;
169
+ const instance = apiInstancesByAddress [ address ] ;
170
+ if ( instance ) {
171
+ return instance [ target . name ] . apply ( instance , actualArgs ) ;
174
172
}
175
173
174
+ /**
175
+ * If a given task is from a contract that is no longer supported and therefore is
176
+ * not wired up when the façade is created, users are still allowed to read from it.
177
+ * To be able to do that, we need to create a new API instnace on the fly for the
178
+ * unsupported contract, but only for the read-only methods.
179
+ */
176
180
if ( ! Object . keys ( readOnlyApiSkeleton ) . includes ( target . name ) ) {
177
181
throw new Error ( `Task with ID ${ ID } is read-only.` ) ;
178
182
}
179
183
180
184
const transientInstance = await createApiInstance ( {
181
185
web3,
182
186
archon,
183
- contracts : await getLinguoContracts ( { web3, chainId, address, deployment : Linguo } ) ,
187
+ contracts : await getContracts ( { web3, chainId, address, deployment : Linguo } ) ,
184
188
} ) ;
185
189
186
- return transientInstance . api [ target . name ] . apply ( actualApi , actualArgs ) ;
190
+ return transientInstance . api [ target . name ] . apply ( instance , actualArgs ) ;
187
191
} ,
188
192
} ;
189
193
@@ -237,7 +241,7 @@ const readOnlyApiSkeleton = {
237
241
getArbitrationCost ( ) { } ,
238
242
} ;
239
243
240
- async function getLinguoContracts ( { web3, chainId, address, deployment } ) {
244
+ async function getContracts ( { web3, chainId, address, deployment } ) {
241
245
// set the max listeners warning threshold
242
246
web3 . eth . maxListenersWarningThreshold = 1000 ;
243
247
@@ -290,63 +294,10 @@ export function getContractInstancesForTranslator({ skills, addressesByLanguageG
290
294
return compose ( Object . values , pick ( addresses ) ) ( apiInstancesByAddress ) ;
291
295
}
292
296
293
- /**
294
- * Considers 1 block each 13.25 seconds on average.
295
- */
296
- const BLOCK_INTERVAL_SIZE = Math . round ( 60 * 24 * 60 * 60 * 4.53 ) ;
297
-
298
- const chainIdToMakeExplorerUrl = {
299
- 1 : ( { account, startBlock, endBlock, apiKey } ) =>
300
- `https://api.etherscan.io/api?module=account&action=txlist&address=${ account } &startblock=${ startBlock } &endblock=${ endBlock } &sort=desc&apikey=${ apiKey } ` ,
301
- 42 : ( { account, startBlock, endBlock, apiKey } ) =>
302
- `https://api-kovan.etherscan.io/api?module=account&action=txlist&address=${ account } &startblock=${ startBlock } &endblock=${ endBlock } &sort=desc&apikey=${ apiKey } ` ,
303
- 77 : ( { account, startBlock, endBlock } ) =>
304
- `https://blockscout.com/poa/sokol/api?module=account&action=txlist&address=${ account } &startblock=${ startBlock } &endblock=${ endBlock } &sort=desc` ,
305
- 100 : ( { account, startBlock, endBlock } ) =>
306
- `https://blockscout.com/xdai/mainnet/api?module=account&action=txlist&address=${ account } &startblock=${ startBlock } &endblock=${ endBlock } &sort=desc` ,
307
- } ;
308
-
309
- async function getContractAddressesForRequester ( { chainId, account, web3, apiInstancesByAddress } ) {
297
+ async function getContractAddressesForRequester ( { account, apiInstancesByAddress } ) {
310
298
if ( ! account ) {
311
299
return [ ] ;
312
300
}
313
301
314
- const endBlock = await web3 . eth . getBlockNumber ( ) ;
315
- const startBlock = subtract ( endBlock , BLOCK_INTERVAL_SIZE ) ;
316
-
317
- const url = chainIdToMakeExplorerUrl [ chainId ] ( {
318
- account,
319
- startBlock,
320
- endBlock,
321
- apiKey : process . env . ETHERSCAN_API_KEY ,
322
- } ) ;
323
-
324
- let response ;
325
- try {
326
- response = await fetch ( url , { mode : 'cors' } ) ;
327
-
328
- if ( ! [ 200 , 304 ] . includes ( response . status ) ) {
329
- console . warn ( `Failed to fetch Linguo contracts account ${ account } interacted with.` ) ;
330
- return Object . keys ( apiInstancesByAddress ) ;
331
- }
332
- } catch ( err ) {
333
- console . warn ( `Failed to fetch Linguo contracts account ${ account } interacted with:` , err ) ;
334
- return Object . keys ( apiInstancesByAddress ) ;
335
- }
336
-
337
- const { result } = await response . json ( ) ;
338
-
339
- /**
340
- * Etherscan API returns addresses converted all to lowercase.
341
- * To actually be able to compare them, we need to convert everything to lowercase
342
- * and then back when returning.
343
- */
344
- const addressesLowercaseKey = indexBy ( addr => String ( addr ) . toLowerCase ( ) , Object . keys ( apiInstancesByAddress ) ) ;
345
-
346
- return compose (
347
- map ( lowercaseAddr => addressesLowercaseKey [ lowercaseAddr ] ) ,
348
- uniq ,
349
- map ( prop ( 'to' ) ) ,
350
- filter ( compose ( to => prop ( to , addressesLowercaseKey ) , prop ( 'to' ) ) )
351
- ) ( result ) ;
302
+ return Object . keys ( apiInstancesByAddress ) ;
352
303
}
0 commit comments