11import IArbitrator from '@kleros/erc-792/build/contracts/IArbitrator.json' ;
22import Linguo from '@kleros/linguo-contracts/artifacts/contracts/0.7.x/Linguo.sol/Linguo.json' ;
3- import { subtract } from '~/adapters/big-number' ;
43import { combination } from '~/adapters/js-combinatorics' ;
54import { withProvider } from '~/app/archon' ;
65import {
98 compose ,
109 filter ,
1110 flatten ,
12- indexBy ,
1311 map ,
1412 mapValues ,
1513 omit ,
@@ -32,7 +30,7 @@ export default async function createApiFacade({ web3, chainId }) {
3230 createApiInstance ( {
3331 web3,
3432 archon,
35- contracts : await getLinguoContracts ( { web3, chainId, address, deployment : Linguo } ) ,
33+ contracts : await getContracts ( { web3, chainId, address, deployment : Linguo } ) ,
3634 } )
3735 ) ,
3836 addressesByLanguageGroupPair
@@ -134,7 +132,7 @@ export default async function createApiFacade({ web3, chainId }) {
134132
135133 const addresses = uniq ( [
136134 ...hintedAddresses ,
137- ...( await getContractAddressesForRequester ( { web3 , chainId , account, apiInstancesByAddress } ) ) ,
135+ ...( await getContractAddressesForRequester ( { account, apiInstancesByAddress } ) ) ,
138136 ] ) ;
139137
140138 const instances = Object . values ( pick ( addresses , apiInstancesByAddress ) ) ;
@@ -168,22 +166,28 @@ export default async function createApiFacade({ web3, chainId }) {
168166 ...rest ,
169167 ] ;
170168
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 ) ;
174172 }
175173
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+ */
176180 if ( ! Object . keys ( readOnlyApiSkeleton ) . includes ( target . name ) ) {
177181 throw new Error ( `Task with ID ${ ID } is read-only.` ) ;
178182 }
179183
180184 const transientInstance = await createApiInstance ( {
181185 web3,
182186 archon,
183- contracts : await getLinguoContracts ( { web3, chainId, address, deployment : Linguo } ) ,
187+ contracts : await getContracts ( { web3, chainId, address, deployment : Linguo } ) ,
184188 } ) ;
185189
186- return transientInstance . api [ target . name ] . apply ( actualApi , actualArgs ) ;
190+ return transientInstance . api [ target . name ] . apply ( instance , actualArgs ) ;
187191 } ,
188192 } ;
189193
@@ -237,7 +241,7 @@ const readOnlyApiSkeleton = {
237241 getArbitrationCost ( ) { } ,
238242} ;
239243
240- async function getLinguoContracts ( { web3, chainId, address, deployment } ) {
244+ async function getContracts ( { web3, chainId, address, deployment } ) {
241245 // set the max listeners warning threshold
242246 web3 . eth . maxListenersWarningThreshold = 1000 ;
243247
@@ -290,63 +294,10 @@ export function getContractInstancesForTranslator({ skills, addressesByLanguageG
290294 return compose ( Object . values , pick ( addresses ) ) ( apiInstancesByAddress ) ;
291295}
292296
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 } ) {
310298 if ( ! account ) {
311299 return [ ] ;
312300 }
313301
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 ) ;
352303}
0 commit comments