Skip to content

Commit

Permalink
Improve TokenIcon (#3365)
Browse files Browse the repository at this point in the history
* Improve consistency of TokenIcons and fix Opensea feed
* Remove WC1 code
* Add clickable Walletconnect icon to main page for WC sessions
  • Loading branch information
JamesSmartCell authored Mar 11, 2024
1 parent 50efab6 commit f6f782f
Show file tree
Hide file tree
Showing 69 changed files with 847 additions and 3,425 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ jobs:
PR_NUMBER: ${{ github.event.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./gradlew report -PgithubPullRequestId=$PR_NUMBER -PgithubToken=$GITHUB_TOKEN
./gradlew report --no-configuration-cache -PgithubPullRequestId=$PR_NUMBER -PgithubToken=$GITHUB_TOKEN
14 changes: 7 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ tasks.withType(Test).configureEach {
}

detekt {
toolVersion = "1.20.0-RC1"
toolVersion = "1.23.5"
buildUponDefaultConfig = true // preconfigure defaults
allRules = false // activate all available (even unstable) rules.
baseline = file("$projectDir/check/detekt-baseline.xml")
Expand Down Expand Up @@ -209,7 +209,7 @@ tasks.register("jacocoAndroidUnitTestReport") {
def fileFilter = ['**/R.class', '**/R$*.class', '**/*$ViewInjector*.*', '**/BuildConfig.*', '**/Manifest*.*', '**/*Realm*.*', '**/Generated*.*', '**/*_*.*']
def debugTree = fileTree(dir: "**/", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"

sourceDirectories.setFrom(files([mainSrc]))
classDirectories.setFrom(files([debugTree]))
}
Expand All @@ -219,9 +219,9 @@ dependencies {

implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation fileTree(include: ['*.aar'], dir: 'libs')
//NB: Downgrade jackson due to bug in 2.15 releases that makes it incompatible with Gradle 8
//noinspection GradleDependency
implementation platform('com.fasterxml.jackson:jackson-bom:2.13.5') //Don't upgrade from 2.13.5 due to Android API24 compatibility

//noinspection BomWithoutPlatform,GradleDependency
implementation platform('com.fasterxml.jackson:jackson-bom:2.13.5') //Do not upgrade! 2.13.5 is latest library with Android API24 compatibility
implementation 'com.fasterxml.jackson.core:jackson-core'
implementation 'com.fasterxml.jackson.core:jackson-databind'

Expand Down Expand Up @@ -282,8 +282,8 @@ dependencies {
//Timber
implementation libs.timber

//noinspection UseTomlInstead
implementation platform('com.walletconnect:android-bom:1.13.1')
//noinspection UseTomlInstead,GradleDependency
implementation platform('com.walletconnect:android-bom:1.13.1') //TODO: Upgrade
implementation("com.walletconnect:android-core", {
exclude group: 'org.web3j', module: '*'
})
Expand Down
5 changes: 0 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<application
android:name=".App"
android:allowBackup="false"
android:extractNativeLibs="true"
android:hardwareAccelerated="false"
android:largeHeap="true"
android:icon="@mipmap/ic_launcher"
Expand Down Expand Up @@ -123,10 +122,6 @@
android:name=".ui.SplashActivity"
android:theme="@style/AppTheme.NoActionBar.Splash" />

<service
android:name=".service.WalletConnectService"
android:enabled="true" />

<service
android:name=".service.WalletConnectV2Service"
android:enabled="true"
Expand Down
19 changes: 2 additions & 17 deletions app/src/main/java/com/alphawallet/app/C.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,23 +313,8 @@ public enum TokenStatus {

// OpenSea APIs
public static final String OPENSEA_COLLECTION_API_MAINNET = "https://api.opensea.io/collection/";

public static final String OPENSEA_ASSETS_API_MAINNET = "https://api.opensea.io/api/v1/assets";
public static final String OPENSEA_ASSETS_API_TESTNET = "https://testnets-api.opensea.io/api/v1/assets";
public static final String OPENSEA_ASSETS_API_MATIC = "https://api.opensea.io/api/v2/assets/matic";
public static final String OPENSEA_ASSETS_API_ARBITRUM = "https://api.opensea.io/api/v2/assets/arbitrum";
public static final String OPENSEA_ASSETS_API_AVALANCHE = "https://api.opensea.io/api/v2/assets/avalanche";
public static final String OPENSEA_ASSETS_API_KLAYTN = "https://api.opensea.io/api/v2/assets/klaytn";
public static final String OPENSEA_ASSETS_API_OPTIMISM = "https://api.opensea.io/api/v2/assets/optimism";

public static final String OPENSEA_SINGLE_ASSET_API_MAINNET = "https://api.opensea.io/api/v1/asset/";
public static final String OPENSEA_SINGLE_ASSET_API_TESTNET = "https://testnets-api.opensea.io/api/v1/asset/";
public static final String OPENSEA_SINGLE_ASSET_API_MATIC = "https://api.opensea.io/api/v2/metadata/matic/";
public static final String OPENSEA_SINGLE_ASSET_API_ARBITRUM = "https://api.opensea.io/api/v2/metadata/arbitrum/";
public static final String OPENSEA_SINGLE_ASSET_API_AVALANCHE = "https://api.opensea.io/api/v2/metadata/avalanche/";
public static final String OPENSEA_SINGLE_ASSET_API_KLAYTN = "https://api.opensea.io/api/v2/metadata/klaytn/";
public static final String OPENSEA_SINGLE_ASSET_API_OPTIMISM = "https://api.opensea.io/api/v2/metadata/optimism/";

public static final String OPENSEA_ASSETS_API_V2 = "https://api.opensea.io/api/v2/chain/{CHAIN}/account/{ADDRESS}/nfts";
public static final String OPENSEA_NFT_API_V2 = "https://api.opensea.io/api/v2/chain/{CHAIN}/contract/{ADDRESS}/nfts/{TOKEN_ID}";

//Timing
public static long CONNECT_TIMEOUT = 10; //Seconds
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ public Single<List<String>> getScriptFileURI()
return Single.fromCallable(() -> callSmartContractFuncAdaptiveArray(token.tokenInfo.chainId, getScriptURI(), token.getAddress(), token.getWallet())).observeOn(Schedulers.io());
}

public Single<String> getContractURIResult()
{
return Single.fromCallable(() -> callSmartContractFunction(token.tokenInfo.chainId, getContractURI(), token.getAddress(), token.getWallet()))
.map(this::loadMetaData)
.observeOn(Schedulers.io());
}

private String loadMetaData(String tokenURI)
{
if (TextUtils.isEmpty(tokenURI))
Expand All @@ -65,7 +72,7 @@ public NFTAsset fetchTokenMetadata(BigInteger tokenId)
{
//1. get TokenURI (check for non-standard URI - check "tokenURI" and "uri")
String responseValue = callSmartContractFunction(token.tokenInfo.chainId, getTokenURI(tokenId), token.getAddress(), token.getWallet());
if (responseValue == null)
if (TextUtils.isEmpty(responseValue))
{
responseValue = callSmartContractFunction(token.tokenInfo.chainId, getTokenURI2(tokenId), token.getAddress(), token.getWallet());
}
Expand Down Expand Up @@ -102,6 +109,12 @@ private static Function getScriptURI() {
Collections.singletonList(new TypeReference<Utf8String>() {}));
}

private static Function getContractURI() {
return new Function("contractURI",
Collections.emptyList(),
Collections.singletonList(new TypeReference<Utf8String>() {}));
}

private static void setupClient()
{
if (client == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ public interface HomeCommsInterface
void backupSuccess(String keyAddress);
void resetTokens();
void resetTransactions();
void openWalletConnect(String sessionId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ public void onReceive(Context context, Intent intent)
String keyAddress = bundle != null ? bundle.getString("Key", "") : "";
homeCommsInterface.backupSuccess(keyAddress);
break;
case C.WALLET_CONNECT_REQUEST:
String sessionId = bundle != null ? bundle.getString("sessionid", "") : "";
homeCommsInterface.openWalletConnect(sessionId);
default:
break;
}
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/java/com/alphawallet/app/entity/ImageEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.alphawallet.app.entity;

public class ImageEntry
{
final public long chainId;
final public String address;
final public String imageUrl;

public ImageEntry(long networkId, String address, String imageUrl)
{
this.chainId = networkId;
this.address = address;
this.imageUrl = imageUrl;
}
}
22 changes: 14 additions & 8 deletions app/src/main/java/com/alphawallet/app/entity/SuggestEIP1559.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private const val extraPriorityFeeRatio = 0.25 // extra priority fee offere
private const val fallbackPriorityFee = 2000000000L // priority fee offered when there are no recent transactions
private const val MIN_PRIORITY_FEE = 100000000L // Minimum priority fee in Wei, 0.1 Gwei

fun SuggestEIP1559(gasService: GasService, feeHistory: FeeHistory): Single<MutableMap<Int, EIP1559FeeOracleResult>> {
fun suggestEIP1559(gasService: GasService, feeHistory: FeeHistory): Single<MutableMap<Int, EIP1559FeeOracleResult>> {
return suggestPriorityFee(parseLong(feeHistory.oldestBlock.removePrefix("0x"), 16), feeHistory, gasService)
.flatMap { priorityFee -> calculateResult(priorityFee, feeHistory) }
}
Expand All @@ -56,22 +56,28 @@ private fun calculateResult(priorityFee: BigInteger, feeHistory: FeeHistory): Si
baseFee[baseFee.size - 1] = (baseFee[baseFee.size - 1].toBigDecimal() * BigDecimal(9 / 8.0)).toBigInteger()
}

((feeHistory.gasUsedRatio.size - 1) downTo 0).forEach { i ->
for (i in (feeHistory.gasUsedRatio.size - 1) downTo 0) {
if (feeHistory.gasUsedRatio[i] > 0.9) {
baseFee[i] = baseFee[i + 1]
}
}

/*((feeHistory.gasUsedRatio.size - 1) downTo 0).forEach { i ->
if (feeHistory.gasUsedRatio[i] > 0.9) {
baseFee[i] = baseFee[i + 1]
}
}*/

val order = (0..feeHistory.gasUsedRatio.size).map { it }.sortedBy { baseFee[it] }

var maxBaseFee = ZERO
val result = mutableMapOf<Int, EIP1559FeeOracleResult>()
(maxTimeFactor downTo 0).forEach { timeFactor ->
for (timeFactor in maxTimeFactor downTo 0) {
var bf: BigInteger
if (timeFactor < 1e-6) {
bf = baseFee.last()
bf = if (timeFactor < 1e-6) {
baseFee.last()
} else {
bf = predictMinBaseFee(baseFee, order, timeFactor.toDouble(), consistentBaseFee)
predictMinBaseFee(baseFee, order, timeFactor.toDouble(), consistentBaseFee)
}
var t = BigDecimal(usePriorityFee)
if (bf > maxBaseFee) {
Expand Down Expand Up @@ -145,8 +151,8 @@ internal fun suggestPriorityFee(firstBlock: Long, feeHistory: FeeHistory, gasSer
rewardPercentile.toString()).blockingGet();

val rewardSize = feeHistoryFetch?.reward?.size ?: 0
(0 until rewardSize).forEach {
rewards.add(BigInteger(Numeric.cleanHexPrefix(feeHistoryFetch.reward[it][0].removePrefix("0x")),
for (index in 0 until rewardSize) {
rewards.add(BigInteger(Numeric.cleanHexPrefix(feeHistoryFetch.reward[index][0].removePrefix("0x")),
16))
}
if (rewardSize < blockCount) break
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ public NFTAsset[] newArray(int size)
};
private static final String LOADING_TOKEN = "*Loading*";
private static final String ID = "id";
private static final String OPENSEA_ID = "identifier";
private static final String ATTN_ID = "attn_id";
private static final String NAME = "name";
private static final String IMAGE = "image";
private static final String IMAGE_URL = "image_url";
private static final String IMAGE_PREVIEW = "image_preview_url";
private static final String COLLECTION = "collection";
private static final String DESCRIPTION = "description";
private static final String IMAGE_ORIGINAL_URL = "image_original_url";
private static final String IMAGE_ANIMATION = "animation_url";
Expand All @@ -66,7 +68,7 @@ public NFTAsset[] newArray(int size)
private static final String[] IMAGE_THUMBNAIL_DESIGNATORS = {IMAGE_PREVIEW, IMAGE, IMAGE_URL, IMAGE_ORIGINAL_URL, IMAGE_ANIMATION};
private static final String BACKGROUND_COLOUR = "background_color";
private static final String EXTERNAL_LINK = "external_link";
private static final List<String> DESIRED_PARAMS = Arrays.asList(NAME, BACKGROUND_COLOUR, IMAGE_URL, IMAGE, IMAGE_ORIGINAL_URL, IMAGE_PREVIEW, DESCRIPTION, EXTERNAL_LINK, IMAGE_ANIMATION);
private static final List<String> DESIRED_PARAMS = Arrays.asList(NAME, BACKGROUND_COLOUR, IMAGE_URL, IMAGE, IMAGE_ORIGINAL_URL, IMAGE_PREVIEW, DESCRIPTION, EXTERNAL_LINK, IMAGE_ANIMATION, COLLECTION);
private static final List<String> ATTRIBUTE_DESCRIPTOR = Arrays.asList("attributes", "traits");
private final Map<String, String> assetMap = new HashMap<>();
private final Map<String, String> attributeMap = new HashMap<>();
Expand Down Expand Up @@ -265,14 +267,19 @@ private void loadFromMetaData(String metaData)
try
{
JSONObject jsonData = new JSONObject(metaData);
if (jsonData.has("nft"))
{
//need to unwrap this return value
jsonData = jsonData.getJSONObject("nft");
}
Iterator<String> keys = jsonData.keys();
String id = null;

while (keys.hasNext())
{
String key = keys.next();
String value = jsonData.getString(key);
if (key.equals(ID))
if (key.equals(ID) || key.equals(OPENSEA_ID))
{
id = value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,22 @@ && getNFTTokenId(tokenId).compareTo(BigInteger.valueOf(0xFFFF)) < 0
&& getNFTTokenId(tokenId).compareTo(BigInteger.ZERO) > 0;
}

@Override
public String getFirstImageUrl()
{
if (assets != null && !assets.isEmpty() && assets.values().stream().findFirst().isPresent())
{
//get first asset
NFTAsset firstAsset = assets.values().stream().findFirst().get();
if (firstAsset.hasImageAsset())
{
return firstAsset.getThumbnail();
}
}

return "";
}

@Override
public boolean isBatchTransferAvailable()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ private void updateEnumerableBalance(Web3j web3j, Realm realm) throws IOExceptio
{
// find tokenId from index
String tokenId = callSmartContractFunction(tokenInfo.chainId, tokenOfOwnerByIndex(BigInteger.valueOf(tokenIndex)), getAddress(), getWallet());
if (tokenId == null) continue;
if (TextUtils.isEmpty(tokenId)) continue;
tokenIdsHeld.add(new BigInteger(tokenId));
}
}
Expand Down Expand Up @@ -620,7 +620,7 @@ private HashSet<BigInteger> checkBalances(Web3j web3j, HashSet<BigInteger> event
for (BigInteger tokenId : eventIds)
{
String owner = callSmartContractFunction(tokenInfo.chainId, ownerOf(tokenId), getAddress(), getWallet());
if (owner == null || owner.equalsIgnoreCase(getWallet()))
if (TextUtils.isEmpty(owner) || owner.equalsIgnoreCase(getWallet()))
{
heldTokens.add(tokenId);
}
Expand Down Expand Up @@ -728,6 +728,22 @@ public EthFilter getSendBalanceFilter(Event event, DefaultBlockParameter startBl
return filter;
}

@Override
public String getFirstImageUrl()
{
if (tokenBalanceAssets != null && !tokenBalanceAssets.isEmpty() && tokenBalanceAssets.values().stream().findFirst().isPresent())
{
//get first asset
NFTAsset firstAsset = tokenBalanceAssets.values().stream().findFirst().get();
if (firstAsset.hasImageAsset())
{
return firstAsset.getThumbnail();
}
}

return "";
}

public String getTransferID(Transaction tx)
{
if (tx.transactionInput != null && tx.transactionInput.miscData.size() > 0)
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/alphawallet/app/entity/tokens/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,11 @@ public Single<List<String>> getScriptURI()
return contractInteract.getScriptFileURI();
}

public Single<String> getContractURI()
{
return contractInteract.getContractURIResult();
}

/**
* Event filters for send and receive of the token, overriden by the token type
*/
Expand Down Expand Up @@ -1153,4 +1158,9 @@ public String getAttestationCollectionId(TokenDefinition td)
{
return getTSKey();
}

public String getFirstImageUrl()
{
return "";
}
}
Loading

0 comments on commit f6f782f

Please sign in to comment.