22
33import static com .alphawallet .app .repository .TokenRepository .getWeb3jService ;
44import static com .alphawallet .app .repository .TokensRealmSource .IMAGES_DB ;
5+ import static com .alphawallet .ethereum .EthereumNetworkBase .MAINNET_ID ;
6+ import static com .alphawallet .token .tools .TokenDefinition .TOKENSCRIPT_ADDRESS ;
7+ import static com .alphawallet .token .tools .TokenDefinition .TOKENSCRIPT_CHAIN ;
58import static com .alphawallet .token .tools .TokenDefinition .TOKENSCRIPT_CURRENT_SCHEMA ;
69import static com .alphawallet .token .tools .TokenDefinition .TOKENSCRIPT_REPO_SERVER ;
10+ import static com .alphawallet .token .tools .TokenDefinition .TOKENSCRIPT_STORE_SERVER ;
711import static com .alphawallet .token .tools .TokenDefinition .UNCHANGED_SCRIPT ;
812
913import android .Manifest ;
6771import com .alphawallet .token .tools .TokenDefinition ;
6872
6973import org .jetbrains .annotations .NotNull ;
74+ import org .json .JSONArray ;
75+ import org .json .JSONObject ;
7076import org .web3j .abi .DefaultFunctionEncoder ;
7177import org .web3j .abi .FunctionEncoder ;
7278import org .web3j .abi .datatypes .Function ;
@@ -385,9 +391,10 @@ private void handleFileLoadError(Throwable throwable, File file)
385391
386392 private TokenDefinition fileLoadComplete (List <ContractLocator > originContracts , TokenScriptFile file , TokenDefinition td )
387393 {
388- if (originContracts .size () == 0 || td .getAttestation () != null ) return td ; //no action needed, not accessible to Attestation //TODO: Refactor once we handle multiple attestations
394+ if (originContracts .isEmpty () || td .getAttestation () != null ) return td ; //no action needed, not accessible to Attestation //TODO: Refactor once we handle multiple attestations
389395
390396 boolean hasEvents = td .hasEvents ();
397+ long primaryChainId = !originContracts .isEmpty () ? originContracts .iterator ().next ().chainId : MAINNET_ID ;
391398
392399 try (Realm realm = realmManager .getRealmInstance (ASSET_DEFINITION_DB ))
393400 {
@@ -396,7 +403,7 @@ private TokenDefinition fileLoadComplete(List<ContractLocator> originContracts,
396403 {
397404 //delete this file and check downloads for update
398405 removeFile (file .getAbsolutePath ());
399- loadScriptFromServer (getFileName (file ));
406+ loadScriptFromServer (primaryChainId , getFileName (file ));
400407 return td ;
401408 }
402409
@@ -1011,7 +1018,7 @@ private TokenScriptFile locateTokenScriptFile(String fileName)
10111018 * Get asset definition given contract address
10121019 *
10131020 * @param address
1014- * @return
1021+ * @return The Token Definition for the given chain, address
10151022 */
10161023 public TokenDefinition getAssetDefinition (long chainId , String address )
10171024 {
@@ -1026,7 +1033,7 @@ public TokenDefinition getAssetDefinition(long chainId, String address)
10261033 if (assetDef == null && !address .equals ("ethereum" ))
10271034 {
10281035 //try web
1029- loadScriptFromServer (address .toLowerCase ()); //this will complete asynchronously and display will be updated
1036+ loadScriptFromServer (chainId , address .toLowerCase ()); //this will complete asynchronously and display will be updated
10301037 }
10311038
10321039 return assetDef ; // if nothing found use default
@@ -1066,10 +1073,10 @@ public Single<TokenDefinition> getAssetDefinitionASync(long chainId, String addr
10661073 }
10671074
10681075 String convertedAddr = (address .equalsIgnoreCase (tokensService .getCurrentAddress ())) ? "ethereum" : address .toLowerCase ();
1069- return getAssetDefinitionASync (getDefinition (getTSDataKey (chainId , address )), convertedAddr );
1076+ return getAssetDefinitionASync (getDefinition (getTSDataKey (chainId , address )), chainId , convertedAddr );
10701077 }
10711078
1072- private Single <TokenDefinition > getAssetDefinitionASync (final TokenDefinition assetDef , final String contractName )
1079+ private Single <TokenDefinition > getAssetDefinitionASync (final TokenDefinition assetDef , final long chainId , final String contractName )
10731080 {
10741081 if (assetDef != null )
10751082 {
@@ -1078,7 +1085,7 @@ private Single<TokenDefinition> getAssetDefinitionASync(final TokenDefinition as
10781085 else if (!contractName .equals ("ethereum" ))
10791086 {
10801087 //at this stage, this script isn't replacing any existing script, so it's safe to write to database without checking if we need to delete anything
1081- return fetchXMLFromServer (contractName .toLowerCase ())
1088+ return fetchXMLFromServer (chainId , contractName .toLowerCase ())
10821089 .flatMap (this ::handleNewTSFile );
10831090 }
10841091 else return Single .fromCallable (TokenDefinition ::new );
@@ -1095,7 +1102,7 @@ public Single<TokenDefinition> getAssetDefinitionASync(Token token)
10951102 // hold until asset definitions have finished loading
10961103 waitForAssets ();
10971104
1098- return getAssetDefinitionASync (getDefinition (token .getTSKey ()), contractName );
1105+ return getAssetDefinitionASync (getDefinition (token .getTSKey ()), token . tokenInfo . chainId , contractName );
10991106 }
11001107
11011108 private void waitForAssets ()
@@ -1169,12 +1176,12 @@ public String getIssuerName(Token token)
11691176 return issuer ;
11701177 }
11711178
1172- private void loadScriptFromServer (String correctedAddress )
1179+ private void loadScriptFromServer (long chainId , String correctedAddress )
11731180 {
11741181 //first check the last time we tried this session
11751182 if (assetChecked .get (correctedAddress ) == null || (System .currentTimeMillis () > (assetChecked .get (correctedAddress ) + 1000L * 60L * 60L )))
11761183 {
1177- fetchXMLFromServer (correctedAddress )
1184+ fetchXMLFromServer (chainId , correctedAddress )
11781185 .flatMap (this ::handleNewTSFile )
11791186 .subscribeOn (Schedulers .io ())
11801187 .observeOn (AndroidSchedulers .mainThread ())
@@ -1416,23 +1423,23 @@ private boolean matchesExistingScript(Token token, String uri)
14161423 return false ;
14171424 }
14181425
1419- private Single <File > tryServerIfRequired (File contractScript , String address )
1426+ private Single <File > tryServerIfRequired (File contractScript , String address , long chainId )
14201427 {
14211428 if (contractScript .exists () || contractScript .getName ().equals (UNCHANGED_SCRIPT ))
14221429 {
14231430 return Single .fromCallable (() -> contractScript );
14241431 }
14251432 else
14261433 {
1427- return fetchXMLFromServer (address );
1434+ return fetchXMLFromServer (chainId , address );
14281435 }
14291436 }
14301437
1431- private Single <File > fetchXMLFromServer (String address )
1438+ private Single <File > fetchXMLFromServer (long chainId , String address )
14321439 {
14331440 return Single .fromCallable (() -> {
14341441 final File defaultReturn = new File ("" );
1435- if (address .equals ( "" )) return defaultReturn ;
1442+ if (address .isEmpty ( )) return defaultReturn ;
14361443
14371444 File result = getDownloadedXMLFile (address );
14381445
@@ -1459,15 +1466,19 @@ private Single<File> fetchXMLFromServer(String address)
14591466 if (assetChecked .get (address ) != null && (System .currentTimeMillis () > (assetChecked .get (address ) + 1000L * 60L * 60L )))
14601467 return result ;
14611468
1462- String sb = TOKENSCRIPT_REPO_SERVER +
1463- TOKENSCRIPT_CURRENT_SCHEMA +
1464- "/" +
1465- address ;
1469+ //use the updated server
1470+ String sb = TOKENSCRIPT_STORE_SERVER .replace (TOKENSCRIPT_ADDRESS , address ).replace (TOKENSCRIPT_CHAIN , Long .toString (chainId ));
14661471
14671472 Pair <String , Boolean > downloadResponse = downloadScript (sb , fileTime );
1468- if (!TextUtils .isEmpty (downloadResponse .first ))
1473+ String offchainScriptUri = getOffchainScriptUri (downloadResponse );
1474+
1475+ if (!TextUtils .isEmpty (offchainScriptUri ))
14691476 {
1470- result = storeFile (address , downloadResponse );
1477+ downloadResponse = downloadScript (offchainScriptUri , fileTime );
1478+ if (!TextUtils .isEmpty (downloadResponse .first ))
1479+ {
1480+ storeFile (address , downloadResponse );
1481+ }
14711482 }
14721483
14731484 assetChecked .put (address , System .currentTimeMillis ());
@@ -1476,6 +1487,27 @@ private Single<File> fetchXMLFromServer(String address)
14761487 });
14771488 }
14781489
1490+ private String getOffchainScriptUri (Pair <String , Boolean > downloadResponse )
1491+ {
1492+ String offchainScriptResponse = "" ;
1493+ try
1494+ {
1495+ JSONObject response = new JSONObject (downloadResponse .first );
1496+ JSONObject scriptUri = response .getJSONObject ("scriptURI" );
1497+ JSONArray offchainLinks = scriptUri .getJSONArray ("offchain" );
1498+ if (offchainLinks .length () > 0 )
1499+ {
1500+ offchainScriptResponse = offchainLinks .getString (0 );
1501+ }
1502+ }
1503+ catch (Exception e )
1504+ {
1505+ offchainScriptResponse = "" ;
1506+ }
1507+
1508+ return offchainScriptResponse ;
1509+ }
1510+
14791511 private Pair <String , Boolean > downloadScript (String Uri , long currentFileTime )
14801512 {
14811513 if (Uri .equals (UNCHANGED_SCRIPT ))
@@ -3116,7 +3148,7 @@ public Single<TokenDefinition> checkServerForScript(Token token, MutableLiveData
31163148
31173149 //try the contractURI, then server
31183150 return fetchTokenScriptFromContract (token , updateFlag )
3119- .flatMap (file -> tryServerIfRequired (file , token .getAddress ().toLowerCase ()))
3151+ .flatMap (file -> tryServerIfRequired (file , token .getAddress ().toLowerCase (), token . tokenInfo . chainId ))
31203152 .flatMap (this ::handleNewTSFile )
31213153 .subscribeOn (Schedulers .io ())
31223154 .observeOn (AndroidSchedulers .mainThread ());
0 commit comments