Skip to content

Commit

Permalink
MultiversX provider improvement - get chosen ESDTs
Browse files Browse the repository at this point in the history
  • Loading branch information
RedRaton committed Nov 20, 2023
1 parent 41bc850 commit 1d69010
Show file tree
Hide file tree
Showing 13 changed files with 266 additions and 26 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ AllMyCoins is a simple crypto portfolio manager.
- <img src="https://assets.coingecko.com/coins/images/22009/small/lum.png?1640590072" alt="Lum" width="15"/> Lum
- <img src="https://assets.coingecko.com/coins/images/22610/small/dsm.png?1643192656" alt="Desmos" width="15"/> Desmos

##### MultiversX ecosystem
* <img src="https://assets.coingecko.com/coins/images/12335/thumb_2x/Elrond.png" alt="Elrond" width="15"/> MultiversX
From the public address, retrieves:
* EGLD: wallet balance, staking delegation, WEGLD, SEGLD, HSEGLD (not deposited in collateral)
* EDSTs:
- WBTC
- WETH
- USDC
- BUSD
- USDT
- MEX, XMEX
- UTK (+ staked on XExchange)
- HTM (+ staked on XExchange)
- ASH
- RIDE (+ staked on XExchange)
- ITHEUM (+ staked on XExchange)
- CRT (+ staked on XExchange)
- BHAT (+ staked on XExchange)
- ZPAY (+ staked on XExchange)

## Display

<img src="doc/img/allMyCoinsWindow.png" alt="AllMyCoins Window" width="300"/>
Expand Down
103 changes: 103 additions & 0 deletions src/main/java/com/allmycoins/balance/multiversx/ESDT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.allmycoins.balance.multiversx;

enum ESDT {
/* BTC. */
ASH("ASH", "ASH-a642d1"),
/* BHAT. */
BHAT("BHAT", "BHAT-c1fde3"),
/* BTC. */
BTC("WBTC", "WBTC-5349b3"),
/* BUSD. */
BUSD("BUSD", "BUSD-40b57e"),
/* CRT. */
CRT("CRT", "CRT-52decf"),
/* ETH. */
ETH("WETH", "WETH-b4ca29"),
/* HSEGLD - Deposited Hatom Staked EGLD. */
HSEGLD("EGLD", "HSEGLD", "HSEGLD-c13a4e", "HSEGLD"),
/* HTM. */
HTM("HTM", "HTM-f51d55"),
/* ITHEUM. */
ITHEUM("ITHEUM", "ITHEUM-df6f26"),
/* MEX. */
MEX("MEX", "MEX-455c57"),
/* SUTK. */
RIDE("RIDE", "RIDE-7d18e9"),
/* SBHAT. */
SBHAT("BHAT", "SBHAT", "SBHAT-89efd3", "Staked BHAT"),
/* SCRT. */
SCRT("CRT", "SCRT", "SCRT-acbd64", "Staked CRT"),
/* SHTM. */
SHTM("HTM", "SHTM", "SHTM-b8b430", "Staked HTM"),
/* SEGLD - Hatom Staked EGLD. */
SEGLD("EGLD", "SEGLD", "SEGLD-3ad2d0", "SEGLD"),
/* SITHEUM. */
SITHEUM("ITHEUM", "SITHEUM", "SITHEUM-e05083"),
/* SRIDE. */
SRIDE("RIDE", "SRIDE", "SRIDE-4ab1d4", "Staked RIDE"),
/* SUTK. */
SUTK("UTK", "SUTK", "SUTK-ba35f3", "Staked UTK"),
/* SZPAY. */
SZPAY("ZPAY", "SZPAY", "SZPAY-9f1b39", "Staked ZPAY"),
/* USDT. */
USDC("USDC", "USDC-c76f1f"),
/* USDT. */
USDT("USDT", "USDT-f8c08c"),
/* UTK. */
UTK("UTK", "UTK-2f80e9"),
/* WEGLD. */
WEGLD("EGLD", "WEGLD", "WEGLD-bd4d79"),
/* XMEX. */
XMEX("MEX", "XMEX", "XMEX-fda355"),
/* SZPAY. */
ZPAY("ZPAY", "ZPAY-247875");

/*
* Multiple ESDTs can be different version of the same coin. For simplicity,
* they are gathered under the reference token.
*/
private String referenceSymbol;

private String ticker;

private String identifier;

private String source;

ESDT(String aTicker, String aIdentifier) {
referenceSymbol = null;
ticker = aTicker;
identifier = aIdentifier;
source = null;
}

ESDT(String aReferenceSymbol, String aTicker, String aIdentifier) {
referenceSymbol = aReferenceSymbol;
ticker = aTicker;
identifier = aIdentifier;
source = null;
}

ESDT(String aReferenceSymbol, String aTicker, String aIdentifier, String aSource) {
referenceSymbol = aReferenceSymbol;
ticker = aTicker;
identifier = aIdentifier;
source = aSource;
}

public String getTicker() {
return ticker;
}

public String getIdentifier() {
return identifier;
}

public String getReferenceSymbol() {
return referenceSymbol != null ? referenceSymbol : ticker;
}

public String getSource() {
return source == null ? "MVX W" : source;
}
}
24 changes: 24 additions & 0 deletions src/main/java/com/allmycoins/balance/multiversx/ESDTs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.allmycoins.balance.multiversx;

import java.util.List;
import java.util.stream.Collectors;

/**
* Utility class for ESDT tokens.
*/
final class ESDTs {

private static final List<ESDT> ESDTS = List.of(ESDT.values());

private ESDTs() {
/* Empty. */
}

static final List<String> getIdentifiers() {
return ESDTS.stream().map(ESDT::getIdentifier).collect(Collectors.toList());
}

static final ESDT getEsdt(final String ticker) {
return ESDTS.stream().filter(esdt -> esdt.getTicker().equals(ticker)).findFirst().get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public final class MultiversXAddressBalanceJson {
final class MultiversXAddressBalanceJson {

private BigDecimal balance;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import com.allmycoins.request.GetRequest;

public final class MultiversXAddressBalanceRequest implements GetRequest<MultiversXBalanceRequestJson> {
final class MultiversXAddressBalanceRequest implements GetRequest<MultiversXBalanceRequestJson> {

private final String address;

Expand Down Expand Up @@ -37,5 +37,4 @@ public Class<MultiversXBalanceRequestJson> jsonResponseClass() {
public String parameters() {
return "";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public final class MultiversXBalanceRequestJson {
final class MultiversXBalanceRequestJson {

private MultiversXAddressBalanceJson data;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public final class MultiversXDelegationJson {
final class MultiversXDelegationJson {

private BigDecimal userActiveStake;
private BigDecimal claimableRewards;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import com.allmycoins.request.GetRequest;

public final class MultiversXDelegationsRequest implements GetRequest<MultiversXDelegationJson[]> {
final class MultiversXDelegationsRequest implements GetRequest<MultiversXDelegationJson[]> {

private final String address;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.allmycoins.balance.multiversx;

import java.math.BigDecimal;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
final class MultiversXEsdtBalanceJson {

private String ticker;

private Long decimals;

private BigDecimal balance;

public BigDecimal getBalance() {
return balance;
}

public String getTicker() {
return ticker;
}

public Long getDecimals() {
return decimals;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.allmycoins.balance.multiversx;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.allmycoins.request.GetRequest;

public final class MultiversXEsdtBalancesRequest implements GetRequest<MultiversXEsdtBalanceJson[]> {

private final String address;

public MultiversXEsdtBalancesRequest(String pAddress) {
address = pAddress;
}

@Override
public String baseUrl() {
return "https://api.multiversx.com";
}

@Override
public String endPoint() {
return "/accounts/" + address + "/tokens";
}

@Override
public Map<String, String> headers() {
return Collections.emptyMap();
}

@Override
public Class<MultiversXEsdtBalanceJson[]> jsonResponseClass() {
return MultiversXEsdtBalanceJson[].class;
}

@Override
public String parameters() {
String meta = "includeMetaESDT=true";
String fields = "fields=ticker,decimals,balance";
String identifiers = "identifiers=" + String.join(",", ESDTs.getIdentifiers());
return String.join("&", List.of(meta, fields, identifiers));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,65 @@

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.concurrent.Future;
import java.util.List;
import java.util.stream.Collectors;

import com.allmycoins.balance.PublicAddressSingleBalanceProvider;
import com.allmycoins.balance.PublicAddressBalanceProvider;
import com.allmycoins.json.BalanceJson;
import com.allmycoins.utils.BigDecimalUtils;
import com.allmycoins.utils.FutureUtils;
import com.allmycoins.utils.RequestUtils;

public final class MultiversXProvider implements PublicAddressSingleBalanceProvider {
public final class MultiversXProvider implements PublicAddressBalanceProvider {

@Override
public String privateConfigKey() {
return "MULTIVERSX_ADDRESS";
}

@Override
public BalanceJson singleBalance(String publicAddress) {
Future<MultiversXBalanceRequestJson> multiversXBalanceRequestJsonF = RequestUtils
.sendRequestFuture(new MultiversXAddressBalanceRequest(publicAddress));
private BalanceJson getEgldBalance(String publicAddress) {
BigDecimal egldWalletBalance = getEgldWalletBalance(publicAddress);
BigDecimal delegationBalance = getEgldDelegationBalance(publicAddress);

Future<MultiversXDelegationJson[]> multiversXDelegationsJsonF = RequestUtils
.sendRequestFuture(new MultiversXDelegationsRequest(publicAddress));
BigDecimal allEGLDs = egldWalletBalance.add(delegationBalance);
float qty = BigDecimalUtils.decimal18(allEGLDs);

var multiversXBalanceRequestJson = FutureUtils.futureResult(multiversXBalanceRequestJsonF);
MultiversXDelegationJson[] multiversXDelegationsJson = FutureUtils.futureResult(multiversXDelegationsJsonF);
return new BalanceJson("EGLD", qty, "MVX W");
}

BigDecimal delegation = Arrays.stream(multiversXDelegationsJson).map(this::sumBalances).reduce(ZERO,
BIG_DECIMAL_SUM);
private List<BalanceJson> getEgldWalletEsdtBalances(String publicAddress) {
MultiversXEsdtBalanceJson[] esdtBalanceJsons = RequestUtils
.sendRequest(new MultiversXEsdtBalancesRequest(publicAddress));

return List.of(esdtBalanceJsons).stream().map(this::toBalanceJson).collect(Collectors.toList());
}

private BalanceJson toBalanceJson(MultiversXEsdtBalanceJson balance) {
ESDT esdt = ESDTs.getEsdt(balance.getTicker());
return new BalanceJson(esdt.getReferenceSymbol(),
BigDecimalUtils.decimal(balance.getBalance(), balance.getDecimals().intValue()), esdt.getSource());
}

private BigDecimal getEgldWalletBalance(String publicAddress) {
return RequestUtils.sendRequest(new MultiversXAddressBalanceRequest(publicAddress)).getData().getBalance();
}

private BigDecimal getEgldDelegationBalance(String publicAddress) {
MultiversXDelegationJson[] multiversXDelegationsJson = RequestUtils
.sendRequest(new MultiversXDelegationsRequest(publicAddress));
return Arrays.stream(multiversXDelegationsJson).map(this::sumBalances).reduce(ZERO, BIG_DECIMAL_SUM);

BigDecimal allEGLDs = multiversXBalanceRequestJson.getData().getBalance().add(delegation);
float qty = BigDecimalUtils.decimal18(allEGLDs);
return new BalanceJson("EGLD", qty, "MultiversX wallet");
}

private BigDecimal sumBalances(MultiversXDelegationJson delegation) {
BigDecimal undelegated = Arrays.stream(delegation.getUserUndelegatedList()).map(UserUndelegatedJson::getAmount)
.reduce(ZERO, BIG_DECIMAL_SUM);
return delegation.getUserActiveStake().add(delegation.getClaimableRewards()).add(undelegated);
}

@Override
public List<BalanceJson> balance(String publicAddress) {
List<BalanceJson> balances = getEgldWalletEsdtBalances(publicAddress);
balances.add(0, getEgldBalance(publicAddress));
return balances;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public final class UserUndelegatedJson {
final class UserUndelegatedJson {

private BigDecimal amount;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ void testBalances() {

MultiversXProvider provider = new MultiversXProvider();
List<BalanceJson> balance = provider.balances();
assertEquals(1, balance.size());
assertTrue(balance.size() >= 1);
BalanceJson balanceJson = balance.get(0);

assertEquals("EGLD", balanceJson.getAsset());
assertEquals("MultiversX wallet", balanceJson.getSrc());
assertEquals("MVX W", balanceJson.getSrc());
assertTrue(balanceJson.getQty() >= 0.0f);
}

Expand Down

0 comments on commit 1d69010

Please sign in to comment.