Skip to content

Commit

Permalink
Fix TokenScript view (#3344)
Browse files Browse the repository at this point in the history
* Fix Active TokenScript view

* Fix whitelist sites

* Fix for TokenScript display and attribute values

* Update dapps list

* Fix for TokenScript view and refresh of attributes

* update e2e
  • Loading branch information
JamesSmartCell authored Dec 27, 2023
1 parent 9dc6963 commit 3d45201
Show file tree
Hide file tree
Showing 15 changed files with 201 additions and 98 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ jobs:
api-level: [28]
target: [default]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v2

- name: Set up JDK
uses: actions/setup-java@v3
uses: actions/setup-java@v2
with:
distribution: oracle
java-version: 17
architecture: x64

- uses: actions/setup-node@v3
- uses: actions/setup-node@v2
with:
node-version: 16
cache: 'npm'
Expand Down
11 changes: 4 additions & 7 deletions app/src/main/assets/dapps_list.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
[
{"name": "TokenScript", "description": "Smart Token Labs TokenScript Viewer", "url": "https://viewer.tokenscript.org/", "category": "Infrastructure"},
{"name": "SmartLayer", "description": "Smart Token Labs Smart Layer Network", "url": "https://smartlayer.network", "category": "Infrastructure"},
{"name": "X", "description": "Social Media", "url": "https://x.com", "category": "Social Media"},
{"name": "Aave", "description": "A decentralized non-custodial liquidity protocol where users can participate as depositors or borrowers", "url": "https://app.aave.com/", "category": "Finance"},
{"name": "Tbull", "description": "A Utility Token on Binance Smart Chain for Payments for Services", "url": "tbull.live", "category": "Utility"},
{"name": "Rare Coin", "description": "Free Crypto Faucet & Yeild Farming", "url": "make.rare.claims", "category": "Tool"},
{"name": "Eporio", "description": "The cheaper marketplace for NFT - Non Fungible Tokens", "url": "https://epor.io", "category": "Marketplace"},
{"name": "Rare Coin", "description": "Free Crypto Faucet & Yield Farming", "url": "make.rare.claims", "category": "Tool"},
{"name": "DeFiBox", "description": "one-stop DeFi asset, data and protocols aggregation platform", "url": "https://www.defibox.com/index?utm_source=2189969", "category": "Tool"},
{"name": "TokenSets", "description": "Enhance your portfolio with automated asset management strategies.", "url": "https://www.tokensets.com/", "category": "Finance"},
{"name": "State of the ÐApps", "description": "Directory of Decentralized Applications", "url": "https://www.stateofthedapps.com/", "category": "Directory"},
{"name": "BulkSender", "description": "Batch sending of tokens", "url": "https://bulksender.app/", "category": "Finance"},
{"name": "Loanscan", "description": "Get the best return for your Tokens", "url": "https://loanscan.io/", "category": "Finance"},
{"name": "Fuse Studio", "description": "Turning communities into economies", "url": "https://studio.fusenet.io/", "category": "Finance"},
{"name": "Axie Infinity", "description": "Collect and raise fantasy creatures", "url": "https://axieinfinity.com/", "category": "Game"},
{"name": "ChickenHunt", "description": "character-growing IDLE game", "url": "https://chickenhunt.io/", "category": "Game"},
{"name": "CryptoCare", "description": "Social Impact Collectibles", "url": "https://cryptocare.tech/adopt/cryptocare", "category": "Game"},
{"name": "Dice2win", "description": "Simple and fair dice game", "url": "https://dice2.win/", "category": "Game"},
{"name": "Dragonereum", "description": "Own and trade dragons, fight with other players", "url": "https://dapp.dragonereum.io/", "category": "Game"},
{"name": "HyperDragons", "description": "Large scale strategy battle game", "url": "https://hyperdragons.alfakingdom.com/", "category": "Game"},
{"name": "MoveCastle", "description": "Learn Libra Move through game", "url": "https://learnlibramove.com/", "category": "Game"},
{"name": "Last Trip", "description": "A RPG game", "url": "http://lasttrip.matrixdapp.com/", "category": "Game"},
{"name": "LORDLESS", "description": "Be a bounty hunter in my tavern", "url": "https://game.lordless.io/home", "category": "Game"},
{"name": "MLB Crypto Baseball", "description": "Baseball collectible game", "url": "https://mlbcryptobaseball.com", "category": "Game"},
Expand Down Expand Up @@ -51,13 +51,10 @@
{"name": "MakerDAO CDP Portal", "description": "Where you can interact with the Dai Credit System", "url": "https://cdp.makerdao.com/", "category": "Finance"},
{"name": "Nexo", "description": "Instant Crypto Loans", "url": "https://nexo.io/", "category": "Finance"},
{"name": "AirSwap", "description": "Peer-to-Peer trading on Ethereum", "url": "https://instant.airswap.io", "category": "Exchange"},
{"name": "Chibi Fighters", "description": "Chibi Fighters are fierce little warriors that know no mercy", "url": "https://chibifighters.io", "category": "Game"},
{"name": "CryptoKitties", "description": "Collect and breed digital cats!", "url": "https://cryptokitties.co", "category": "Game"},
{"name": "BTU Hotel", "description": "BTU Hotel is a hotel booking Dapp takes 0% commission. Dapp user earns 100% of the hotel commission directly in crypto into their preferred browser wallet", "url": "https://btu-hotel.com", "category": "Travel"},
{"name": "Bidali", "description": "Buy from top brands with crypto", "url": "https://commerce.bidali.com/dapp", "category": "Marketplace"},
{"name": "Zerion", "description": "Trade and manage your digital assets across different wallets in one interface", "url": "https://zerion.io", "category": "Finance"},
{"name": "ENS domain manager", "description": "Manage ENS domains", "url": "https://manager.ens.domains", "category": "Tool"},
{"name": "Humanity", "description": "Human Identity on Ethereum", "url": "https://humanitydao.org", "category": "Social Media"},
{"name": "DEX.AG", "description": "Trade cryptoassets at the best price", "url": "https://dex.ag", "category": "Exchange"},
{"name": "Totle Swap", "description": "Totle automatically finds and acquires the best price across decentralized exchanges for ERC-20 swaps", "url": "https://swap.totle.com", "category": "Exchange"},
{"name": "ATS Bridge", "description": "ATS/ATS20 bridge for self transfers of ATS to ATS20", "url": "https://bridge.artis.network/", "category": "Tool"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ default void handleTokenScriptFunction(String function, List<BigInteger> selecti
default void showWaitSpinner(boolean show) { }

default void handleFunctionDenied(String denialMessage) { }

default void completeFunctionSetup() { }
}
10 changes: 10 additions & 0 deletions app/src/main/java/com/alphawallet/app/entity/TSAttrCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.alphawallet.app.entity;

import com.alphawallet.token.entity.TokenScriptResult;

import java.util.List;

public interface TSAttrCallback
{
void showTSAttributes(List<TokenScriptResult.Attribute> attrs, boolean updateRequired);
}
8 changes: 8 additions & 0 deletions app/src/main/java/com/alphawallet/app/entity/UpdateType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.alphawallet.app.entity;

public enum UpdateType
{
USE_CACHE,
UPDATE_IF_REQUIRED,
ALWAYS_UPDATE
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import android.text.TextUtils;

import com.alphawallet.app.entity.UpdateType;
import com.alphawallet.app.entity.tokens.Token;
import com.alphawallet.app.repository.TokenRepository;
import com.alphawallet.app.util.BalanceUtils;
Expand Down Expand Up @@ -730,6 +731,17 @@ public TokenScriptResult.Attribute parseFunctionResult(TransactionResult transac
if (!TextUtils.isEmpty(res) && res.equalsIgnoreCase("TRUE")) val = BigInteger.ONE;
else val = BigInteger.ZERO;
}
else if (attr.syntax == TokenDefinition.Syntax.Integer)
{
if (transactionResult.result.startsWith("0x"))
{
val = new BigInteger(transactionResult.result, 16);
}
else
{
val = new BigInteger(transactionResult.result);
}
}
else if (attr.syntax == TokenDefinition.Syntax.NumericString && attr.as != As.Address)
{
if (transactionResult.result == null)
Expand Down Expand Up @@ -863,7 +875,8 @@ else if (!TextUtils.isEmpty(element.value))
}
else
{
return fetchAttrResult(token, attr, tokenId, definition, attrIf, ViewType.VIEW).blockingGet().text;
return fetchAttrResult(token, attr, tokenId, definition, attrIf,
ViewType.VIEW, UpdateType.ALWAYS_UPDATE).blockingGet().text;
}

return null;
Expand Down Expand Up @@ -892,14 +905,16 @@ else if (!TextUtils.isEmpty(element.value))
*/

public Single<TokenScriptResult.Attribute> fetchAttrResult(Token token, Attribute attr, BigInteger tokenId,
TokenDefinition td, AttributeInterface attrIf, ViewType itemView)
TokenDefinition td, AttributeInterface attrIf,
ViewType itemView, UpdateType update)
{
final BigInteger useTokenId = (attr == null) ? BigInteger.ZERO : tokenId;
if (attr == null)
{
return Single.fromCallable(() -> new TokenScriptResult.Attribute("bd", "bd", BigInteger.ZERO, ""));
}
else if (token.getAttributeResult(attr.name, useTokenId) != null)

final BigInteger useTokenId = attr.usesTokenId() ? tokenId : BigInteger.ZERO;
if (token.getAttributeResult(attr.name, useTokenId) != null)
{
return Single.fromCallable(() -> token.getAttributeResult(attr.name, useTokenId));
}
Expand Down Expand Up @@ -929,7 +944,10 @@ else if (attr.function == null) // static attribute from tokenId (eg city mappi
ContractAddress useAddress = new ContractAddress(attr.function); //always use the function attribute's address
long lastTxUpdate = attrIf.getLastTokenUpdate(useAddress.chainId, useAddress.address);
TransactionResult cachedResult = attrIf.getFunctionResult(useAddress, attr, useTokenId); //Needs to allow for multiple tokenIds
if ((itemView == ViewType.ITEM_VIEW || (!attr.isVolatile() && ((attrIf.resolveOptimisedAttr(useAddress, attr, cachedResult) || !cachedResult.needsUpdating(lastTxUpdate)))))) //can we use wallet's known data or cached value?
boolean shouldUseCache = checkUpdateRequired(attrIf, attr, cachedResult, update,
itemView == ViewType.ITEM_VIEW, lastTxUpdate, useAddress);

if (shouldUseCache) //can we use wallet's known data or cached value?
{
return resultFromDatabase(cachedResult, attr);
}
Expand All @@ -945,6 +963,27 @@ else if (attr.function == null) // static attribute from tokenId (eg city mappi
}
}

private boolean checkUpdateRequired(AttributeInterface attrIf, Attribute attr,
TransactionResult cachedResult, UpdateType update,
boolean isItemView, long lastTxUpdate,
ContractAddress useAddress)
{
switch (update)
{
case USE_CACHE -> {
return isItemView || !(cachedResult.resultTime == 0); //only update if no result
}
case UPDATE_IF_REQUIRED -> {
return (isItemView || (!attr.isVolatile() && ((attrIf.resolveOptimisedAttr(useAddress, attr, cachedResult) || !cachedResult.needsUpdating(lastTxUpdate)))));
}
case ALWAYS_UPDATE -> {
return isItemView;
}
}

return true;
}

private Single<TokenScriptResult.Attribute> getEventResult(TransactionResult txResult, Attribute attr, BigInteger tokenId, AttributeInterface attrIf)
{
//fetch the function
Expand Down Expand Up @@ -973,7 +1012,12 @@ private Single<TokenScriptResult.Attribute> staticAttribute(Attribute attr, BigI
return Single.fromCallable(() -> {
try
{
if (attr.userInput)
if (refTags.containsKey(attr.name))
{
attr.userInput = false;
return new TokenScriptResult.Attribute(attr.name, attr.label, BigInteger.ZERO, refTags.get(attr.name), false);
}
else if (attr.userInput)
{
return new TokenScriptResult.Attribute(attr.name, attr.label, BigInteger.ZERO, "", true);
}
Expand Down
Loading

0 comments on commit 3d45201

Please sign in to comment.