11package dev .andstuff .kraken .api .endpoint .account .response ;
22
3+ import static java .util .regex .Pattern .matches ;
4+
35import java .math .BigDecimal ;
46import java .time .Instant ;
57import java .time .ZoneId ;
68import java .util .List ;
7- import java .util .regex .Pattern ;
89
910import com .fasterxml .jackson .annotation .JsonEnumDefaultValue ;
1011import com .fasterxml .jackson .annotation .JsonProperty ;
@@ -25,16 +26,24 @@ public record LedgerEntry(@CsvBindByName(column = "txid") @With String id, // TO
2526 @ CsvBindByName (column = "balance" ) BigDecimal balance ) {
2627
2728 /**
28- * Attempts to extract the underlying asset, e.g. DOT.28S returns DOT, XXBT
29+ * Attempts to extract the underlying asset, e.g. DOT28.S returns DOT, XXBT
2930 * returns XBT, ZUSD returns USD.
3031 *
3132 * @return the underlying asset
3233 */
3334 public String underlyingAsset () {
3435 return switch (asset ) {
35- case String s when Pattern .matches ("^[XZ][A-Z]{3}$" , s ) -> s .substring (1 , 4 );
36- case String s when Pattern .matches ("^[0-9A-Z]+$" , s ) -> s ;
36+ // Kraken returns DOGE and BTC when exporting ledger as a file, but uses XDG and XBT in the API
37+ case String s when "DOGE" .equals (s ) -> "XDG" ;
38+ case String s when "BTC" .equals (s ) -> "XBT" ;
39+ // Take care of asset migrations
3740 case String s when "ETH2" .equals (s ) -> "ETH" ;
41+ case String s when matches ("^MATIC(\\ d+\\ .S)?$" , s ) -> "POL" ;
42+ // Remove X or Z prefix for fiat and some cryptos
43+ case String s when matches ("^[XZ][A-Z]{3}$" , s ) -> s .substring (1 , 4 );
44+ // Return asset as is if it only contains numbers and capital letters
45+ case String s when matches ("^[0-9A-Z]+$" , s ) -> s ;
46+ // Strip staking suffix (e.g. `28.S`)
3847 default -> asset .split ("[0-9.]" )[0 ];
3948 };
4049 }
@@ -44,7 +53,9 @@ public BigDecimal netAmount() {
4453 }
4554
4655 public boolean isStakingReward () {
47- return List .of (Type .STAKING , Type .EARN ).contains (type );
56+ boolean isStakingOrEarnType = List .of (Type .STAKING , Type .EARN ).contains (type );
57+ boolean isRewardSubType = !List .of ("allocation" , "deallocation" , "autoallocation" , "migration" ).contains (subType );
58+ return isStakingOrEarnType && isRewardSubType ;
4859 }
4960
5061 public int year () {
0 commit comments