Merging develop into master

master
Nelson R. Perez 2018-01-25 18:01:00 -05:00
commit 077d34a123
136 changed files with 2098 additions and 929 deletions

View File

@ -17,8 +17,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
VERSION_NAME=0.4.4
VERSION_CODE=6
VERSION_NAME=0.4.6
VERSION_CODE=9
GROUP=com.github.bilthon
POM_DESCRIPTION=A Java library for mobile app Developers; Graphene/Bitshares blockchain.

View File

@ -1,5 +1,5 @@
group 'de.bitsharesmunich'
version '0.4.4'
group 'cy.agorise'
version '0.4.6'
apply plugin: 'com.android.library'
apply from: 'maven-push.gradle'
@ -21,9 +21,8 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 24
versionCode 6
versionName "0.4.4"
versionCode 9
versionName "0.4.6"
vectorDrawables.useSupportLibrary = true
}
buildTypes {

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.bitsharesmunich.graphenej"
android:versionCode="5"
android:versionName="0.4.3" >
package="cy.agorise.graphenej"
android:versionCode="9"
android:versionName="0.4.6" >
<uses-sdk android:minSdkVersion="1" />
<application/>
</manifest>

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.Bytes;
import com.google.gson.JsonArray;
@ -12,8 +12,8 @@ import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
import cy.agorise.graphenej.errors.MalformedAddressException;
import cy.agorise.graphenej.interfaces.GrapheneSerializable;
/**
* Created by nelson on 12/5/16.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.Bytes;
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
import cy.agorise.graphenej.errors.MalformedAddressException;
import org.bitcoinj.core.Base58;
import org.bitcoinj.core.ECKey;
import org.spongycastle.crypto.digests.RIPEMD160Digest;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.UnsignedLong;
import com.google.gson.JsonDeserializationContext;
@ -10,7 +10,7 @@ import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
/**
* Created by nelson on 11/9/16.
* Class used to represent a specific asset on the Graphene platform
*/
public class Asset extends GrapheneObject {
public final static String TAG = "Asset";
@ -83,6 +83,22 @@ public class Asset extends GrapheneObject {
this.issuer = issuer;
}
/**
* Copy constructor
* @param asset Another asset instance
*/
public Asset(Asset asset){
super(asset.getObjectId());
this.symbol = asset.getSymbol();
this.precision = asset.getPrecision();
this.issuer = asset.getIssuer();
this.description = asset.getDescription();
this.dynamic_asset_data_id = asset.getDynamicAssetDataId();
this.options = asset.getAssetOptions();
this.bitasset_data_id = asset.getBitassetId();
this.mAssetType = asset.getAssetType();
}
public String getSymbol(){
return this.symbol;
}
@ -111,6 +127,14 @@ public class Asset extends GrapheneObject {
return description;
}
public String getDynamicAssetDataId() {
return dynamic_asset_data_id;
}
public void setDynamicAssetDataId(String dynamic_asset_data_id) {
this.dynamic_asset_data_id = dynamic_asset_data_id;
}
public void setAssetOptions(AssetOptions options){
this.options = options;
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.math.DoubleMath;
import com.google.common.primitives.Bytes;
@ -17,14 +17,15 @@ import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import de.bitsharesmunich.graphenej.errors.IncompatibleOperation;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import cy.agorise.graphenej.errors.IncompatibleOperation;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
/**
* Created by nelson on 11/7/16.
* Class used to represent a specific amount of a certain asset
*/
public class AssetAmount implements ByteSerializable, JsonSerializable {
/**
@ -36,11 +37,25 @@ public class AssetAmount implements ByteSerializable, JsonSerializable {
private UnsignedLong amount;
private Asset asset;
/**
* Class constructor
* @param amount The amount
* @param asset The asset
*/
public AssetAmount(UnsignedLong amount, Asset asset){
this.amount = amount;
this.asset = asset;
}
/**
* Copy constructor
* @param assetAmount The other instance
*/
public AssetAmount(AssetAmount assetAmount){
this.amount = UnsignedLong.valueOf(assetAmount.getAmount().toString());
this.asset = new Asset(assetAmount.getAsset());
}
/**
* Adds two asset amounts. They must refer to the same Asset type.
* @param other: The other AssetAmount to add to this.
@ -91,8 +106,10 @@ public class AssetAmount implements ByteSerializable, JsonSerializable {
* @return The same AssetAmount instance, but with the changed amount value.
*/
public AssetAmount multiplyBy(double factor, RoundingMode roundingMode){
this.amount = UnsignedLong.valueOf(DoubleMath.roundToLong(this.amount.longValue() * factor, roundingMode));
return this;
BigDecimal originalAmount = new BigDecimal(amount.bigIntegerValue());
BigDecimal decimalResult = originalAmount.multiply(new BigDecimal(factor));
UnsignedLong resultingAmount = UnsignedLong.valueOf(DoubleMath.roundToBigInteger(decimalResult.doubleValue(), roundingMode));
return new AssetAmount(resultingAmount, new Asset(asset));
}
/**
@ -110,9 +127,11 @@ public class AssetAmount implements ByteSerializable, JsonSerializable {
* @param divisor: The divisor
* @return: The same AssetAMount instance, but with the divided amount value
*/
public AssetAmount dividedBy(double divisor, RoundingMode roundingMode){
this.amount = UnsignedLong.valueOf(DoubleMath.roundToLong(this.amount.longValue() / divisor, roundingMode));
return this;
public AssetAmount divideBy(double divisor, RoundingMode roundingMode){
BigDecimal originalAmount = new BigDecimal(amount.bigIntegerValue());
BigDecimal decimalAmount = originalAmount.divide(new BigDecimal(divisor), 18, RoundingMode.HALF_UP);
UnsignedLong resultingAmount = UnsignedLong.valueOf(DoubleMath.roundToBigInteger(decimalAmount.doubleValue(), roundingMode));
return new AssetAmount(resultingAmount, new Asset(asset));
}
@ -122,8 +141,8 @@ public class AssetAmount implements ByteSerializable, JsonSerializable {
* @param divisor: The divisor
* @return: The same AssetAMount instance, but with the divided amount value
*/
public AssetAmount dividedBy(double divisor){
return this.dividedBy(divisor, RoundingMode.HALF_DOWN);
public AssetAmount divideBy(double divisor){
return this.divideBy(divisor, RoundingMode.HALF_DOWN);
}
public void setAmount(UnsignedLong amount){
@ -136,6 +155,10 @@ public class AssetAmount implements ByteSerializable, JsonSerializable {
public Asset getAsset(){ return this.asset; }
public void setAsset(Asset asset){
this.asset = asset;
}
@Override
public byte[] toBytes() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.UnsignedLong;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.Bytes;
import com.google.gson.JsonArray;
@ -13,8 +13,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
import cy.agorise.graphenej.errors.MalformedAddressException;
import cy.agorise.graphenej.interfaces.GrapheneSerializable;
/**
* Class used to represent the weighted set of keys and accounts that must approve operations.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
* Enum-type used to specify the different roles of an authority.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import java.util.Arrays;
import org.bitcoinj.core.Base58;

View File

@ -1,9 +1,9 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
/**
* Created by nelson on 11/5/16.

View File

@ -1,6 +1,6 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
/**
* This class encapsulates all block-related information needed in order to build a valid transaction.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import org.bitcoinj.core.DumpedPrivateKey;
import org.bitcoinj.core.ECKey;
@ -10,7 +10,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import de.bitsharesmunich.graphenej.crypto.SecureRandomGenerator;
import cy.agorise.graphenej.crypto.SecureRandomGenerator;
/**
* Class used to encapsulate all BrainKey-related operations.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
* Created by nelson on 11/8/16.

View File

@ -1,10 +1,10 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import java.math.BigDecimal;
import java.math.MathContext;
import de.bitsharesmunich.graphenej.errors.IncompleteAssetError;
import de.bitsharesmunich.graphenej.models.BucketObject;
import cy.agorise.graphenej.errors.IncompleteAssetError;
import cy.agorise.graphenej.models.BucketObject;
/**
* Generic converter class used to translate the market information contained in a BucketObject and/or Price instances.

View File

@ -1,9 +1,9 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
import java.util.ArrayList;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
@ -13,8 +13,8 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener;
import de.bitsharesmunich.graphenej.models.backup.WalletBackup;
import cy.agorise.graphenej.crypto.SecureRandomStrengthener;
import cy.agorise.graphenej.models.backup.WalletBackup;
/**
* Class to manage the backup files

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.annotations.Expose;

View File

@ -1,11 +1,11 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import org.bitcoinj.core.Base58;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
/**
* Class used to handle invoice generation, compression and QR-Code data derivation,

View File

@ -1,5 +1,6 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.UnsignedLong;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
@ -12,7 +13,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
/**
*
@ -28,7 +29,7 @@ public class LimitOrder extends GrapheneObject implements ByteSerializable {
private String expiration;
private UserAccount seller;
private long forSale;
private UnsignedLong forSale;
private long deferredFee;
private Price sellPrice;
@ -52,11 +53,11 @@ public class LimitOrder extends GrapheneObject implements ByteSerializable {
this.seller = seller;
}
public long getForSale() {
public UnsignedLong getForSale() {
return forSale;
}
public void setForSale(long forSale) {
public void setForSale(UnsignedLong forSale) {
this.forSale = forSale;
}
@ -127,7 +128,7 @@ public class LimitOrder extends GrapheneObject implements ByteSerializable {
LimitOrder limitOrder = new LimitOrder(id);
limitOrder.setExpiration(expiration);
limitOrder.setSeller(seller);
limitOrder.setForSale(Long.parseLong(forSale));
limitOrder.setForSale(UnsignedLong.valueOf(forSale));
limitOrder.setSellPrice(price);
limitOrder.setDeferredFee(deferredFee);
return limitOrder;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
* Created by nelson on 1/11/17.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
*

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
* Enum type used to list all possible object types and obtain their space + type id

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
* Enum type used to keep track of all the operation types and their corresponding ids.

View File

@ -1,9 +1,9 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.JsonElement;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.GrapheneSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.GrapheneSerializable;
/**
* Container template class used whenever we have an optional field.

View File

@ -0,0 +1,135 @@
package cy.agorise.graphenej;
import com.google.common.primitives.UnsignedLong;
import java.util.List;
import cy.agorise.graphenej.operations.LimitOrderCreateOperation;
/**
* This class will maintain a snapshot of the order book between two assets.
*
* It also provides a handy method that should return the appropriate LimitOrderCreateOperation
* object needed in case the user wants to perform market-priced operations.
*
* It is important to keep the order book updated, ideally by listening to blockchain events,
* and calling the 'update' method.
*
*/
public class OrderBook {
private List<LimitOrder> limitOrders;
public OrderBook(List<LimitOrder> limitOrders){
this.limitOrders = limitOrders;
}
/**
* Replaces the current limit order by the list provided as parameter.
* @param limitOrders: New list of orders
*/
public void update(List<LimitOrder> limitOrders){
this.limitOrders = limitOrders;
}
public void update(LimitOrder limitOrder){
//TODO: Implement the method that will update a single limit order from the order book
}
/**
* High level method used to exchange a specific amount of an asset (The base) for another
* one (The quote) at market value.
*
* It should analyze the order book and figure out the optimal amount of the base asset to give
* away in order to obtain the desired amount of the quote asset.
*
* @param seller: User account of the seller, used to build the limit order create operation
* @param myBaseAsset: The asset the user is willing to give away
* @param myQuoteAmount: The amount of a given asset the user wants
* @param expiration: The expiration time of the limit order
*
* @return An instance of the LimitOrderCreateOperation class, which is ready to be broadcasted.
*/
public LimitOrderCreateOperation exchange(UserAccount seller, Asset myBaseAsset, AssetAmount myQuoteAmount, int expiration){
AssetAmount toSell = new AssetAmount(calculateRequiredBase(myQuoteAmount), myBaseAsset);
AssetAmount toReceive = myQuoteAmount;
LimitOrderCreateOperation buyOrder = new LimitOrderCreateOperation(seller, toSell, toReceive, expiration, true);
return buyOrder;
}
public LimitOrderCreateOperation exchange(UserAccount seller, AssetAmount baseAmount, Asset quoteAsset, int expiration){
AssetAmount minToReceive = new AssetAmount(calculateObtainedQuote(baseAmount), quoteAsset);
return new LimitOrderCreateOperation(seller, baseAmount, minToReceive, expiration, true);
}
/**
* Method that calculates the amount of an asset that we will obtain (the quote amount) if we trade
* a known fixed amount of the asset we already have (the base amount).
*
* @param baseAmount The fixed amount of the asset we have and want to sell
* @return The equivalent amount to receive in exchange of the base amount
*/
public UnsignedLong calculateObtainedQuote(AssetAmount baseAmount){
UnsignedLong myBase = baseAmount.getAmount();
UnsignedLong obtainedQuote = UnsignedLong.ZERO;
for(int i = 0; i < limitOrders.size() && myBase.compareTo(UnsignedLong.ZERO) > 0; i++){
LimitOrder order = limitOrders.get(i);
// Checking to make sure the order matches our needs
if(order.getSellPrice().quote.getAsset().equals(baseAmount.getAsset())){
UnsignedLong orderBase = order.getSellPrice().base.getAmount();
UnsignedLong orderQuote = order.getSellPrice().quote.getAmount();
UnsignedLong availableBase = order.getForSale();
UnsignedLong myQuote = UnsignedLong.valueOf((long)(myBase.times(orderBase).doubleValue() / (orderQuote.doubleValue())));
if(myQuote.compareTo(availableBase) > 0){
// We consume this order entirely
// myBase = myBase - (for_sale) * (order_quote / order_base)
myBase = myBase.minus(availableBase.times(orderQuote).dividedBy(orderBase));
// We need more than this order can offer us, but have to take in consideration how much there really is.
// (order base / order quote) x (available order base / order base)
UnsignedLong thisBatch = UnsignedLong.valueOf((long)(orderBase.times(availableBase).doubleValue() / orderQuote.times(orderBase).doubleValue()));
obtainedQuote = obtainedQuote.plus(thisBatch);
}else{
// This order consumes all our base asset
// obtained_quote = obtained_quote + (my base * order_base / order_quote)
obtainedQuote = obtainedQuote.plus(myBase.times(orderBase).dividedBy(orderQuote));
myBase = UnsignedLong.ZERO;
}
}
}
return obtainedQuote;
}
/**
* Method that calculates the amount of an asset that we will consume (the base amount) if we want to obtain
* a known fixed amount of another asset (the quote amount).
* @param quoteAmount The fixed amount of an asset that we want to obtain
* @return The amount of an asset we already have that will be consumed by the trade
*/
public UnsignedLong calculateRequiredBase(AssetAmount quoteAmount){
UnsignedLong myQuote = quoteAmount.getAmount();
UnsignedLong obtainedBase = UnsignedLong.ZERO;
for(int i = 0; i < limitOrders.size() && myQuote.compareTo(UnsignedLong.ZERO) > 0; i++){
LimitOrder order = limitOrders.get(i);
// Checking to make sure the order matches our needs
if(order.getSellPrice().base.getAsset().equals(quoteAmount.getAsset())){
UnsignedLong orderBase = order.getSellPrice().base.getAmount();
UnsignedLong orderQuote = order.getSellPrice().quote.getAmount();
UnsignedLong forSale = order.getForSale();
if(forSale.compareTo(myQuote) > 0){
// Found an order that fills our requirements
obtainedBase = obtainedBase.plus(UnsignedLong.valueOf((long) (myQuote.doubleValue() * orderQuote.doubleValue() / orderBase.doubleValue())));
myQuote = UnsignedLong.ZERO;
}else{
// Found an order that partially fills our needs
obtainedBase = obtainedBase.plus(UnsignedLong.valueOf((long) (forSale.doubleValue() * orderQuote.doubleValue() / orderBase.doubleValue())));
myQuote = myQuote.minus(forSale);
}
}
}
return obtainedBase;
}
}

View File

@ -1,11 +1,4 @@
package de.bitsharesmunich.graphenej;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
package cy.agorise.graphenej;
/**
* The price struct stores asset prices in the Graphene system.

View File

@ -1,11 +1,11 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import org.bitcoinj.core.ECKey;
import org.spongycastle.math.ec.ECPoint;
import java.io.Serializable;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
/**
* Created by nelson on 11/30/16.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
/**
* Created by nelson on 11/16/16.
@ -25,6 +25,7 @@ public class RPC {
public static final String GET_ACCOUNT_BALANCES = "get_account_balances";
public static final String CALL_LOOKUP_ASSET_SYMBOLS = "lookup_asset_symbols";
public static final String CALL_GET_BLOCK_HEADER = "get_block_header";
public static final String CALL_GET_BLOCK = "get_block";
public static final String CALL_GET_LIMIT_ORDERS = "get_limit_orders";
public static final String CALL_GET_TRADE_HISTORY = "get_trade_history";
public static final String CALL_GET_MARKET_HISTORY = "get_market_history";

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.Bytes;
import com.google.gson.GsonBuilder;
@ -24,10 +24,11 @@ import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import de.bitsharesmunich.graphenej.operations.LimitOrderCreateOperation;
import de.bitsharesmunich.graphenej.operations.TransferOperation;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
import cy.agorise.graphenej.operations.CustomOperation;
import cy.agorise.graphenej.operations.LimitOrderCreateOperation;
import cy.agorise.graphenej.operations.TransferOperation;
/**
* Class used to represent a generic Graphene transaction.
@ -45,29 +46,43 @@ public class Transaction implements ByteSerializable, JsonSerializable {
public static final String KEY_REF_BLOCK_NUM = "ref_block_num";
public static final String KEY_REF_BLOCK_PREFIX = "ref_block_prefix";
// Using the bitshares mainnet chain id by default
private byte[] chainId = Util.hexToBytes(Chains.BITSHARES.CHAIN_ID);
private ECKey privateKey;
private BlockData blockData;
private List<BaseOperation> operations;
private Extensions extensions;
/**
* Transaction constructor.
* @param privateKey : Instance of a ECKey containing the private key that will be used to sign this transaction.
* @param blockData : Block data containing important information used to sign a transaction.
* @param operationList : List of operations to include in the transaction.
* Transaction constructor
* @param chainId The chain id
* @param privateKey Private key used to sign this transaction
* @param blockData Block data
* @param operations List of operations contained in this transaction
*/
public Transaction(ECKey privateKey, BlockData blockData, List<BaseOperation> operationList){
public Transaction(byte[] chainId, ECKey privateKey, BlockData blockData, List<BaseOperation> operations){
this.chainId = chainId;
this.privateKey = privateKey;
this.blockData = blockData;
this.operations = operationList;
this.operations = operations;
this.extensions = new Extensions();
}
/**
* Transaction constructor.
* @param wif: The user's private key in the base58 format.
* @param block_data: Block data containing important information used to sign a transaction.
* @param operation_list: List of operations to include in the transaction.
* @param privateKey Instance of a ECKey containing the private key that will be used to sign this transaction.
* @param blockData Block data containing important information used to sign a transaction.
* @param operationList List of operations to include in the transaction.
*/
public Transaction(ECKey privateKey, BlockData blockData, List<BaseOperation> operationList){
this(Util.hexToBytes(Chains.BITSHARES.CHAIN_ID), privateKey, blockData, operationList);
}
/**
* Transaction constructor.
* @param wif The user's private key in the base58 format.
* @param block_data Block data containing important information used to sign a transaction.
* @param operation_list List of operations to include in the transaction.
*/
public Transaction(String wif, BlockData block_data, List<BaseOperation> operation_list){
this(DumpedPrivateKey.fromBase58(null, wif).getKey(), block_data, operation_list);
@ -76,8 +91,8 @@ public class Transaction implements ByteSerializable, JsonSerializable {
/**
* Constructor used to build a Transaction object without a private key. This kind of object
* is used to represent a transaction data that we don't intend to serialize and sign.
* @param blockData: Block data instance, containing information about the location of this transaction in the blockchain.
* @param operationList: The list of operations included in this transaction.
* @param blockData Block data instance, containing information about the location of this transaction in the blockchain.
* @param operationList The list of operations included in this transaction.
*/
public Transaction(BlockData blockData, List<BaseOperation> operationList){
this.blockData = blockData;
@ -86,7 +101,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
/**
* Updates the block data
* @param blockData: New block data
* @param blockData New block data
*/
public void setBlockData(BlockData blockData){
this.blockData = blockData;
@ -161,6 +176,18 @@ public class Transaction implements ByteSerializable, JsonSerializable {
return sigData;
}
public void setChainId(String chainId){
this.chainId = Util.hexToBytes(chainId);
}
public void setChainId(byte[] chainId){
this.chainId = chainId;
}
public byte[] getChainId(){
return this.chainId;
}
/**
* Method that creates a serialized byte array with compact information about this transaction
* that is needed for the creation of a signature.
@ -169,7 +196,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
public byte[] toBytes(){
// Creating a List of Bytes and adding the first bytes from the chain apiId
List<Byte> byteArray = new ArrayList<Byte>();
byteArray.addAll(Bytes.asList(Util.hexToBytes(Chains.BITSHARES.CHAIN_ID)));
byteArray.addAll(Bytes.asList(chainId));
// Adding the block data
byteArray.addAll(Bytes.asList(this.blockData.toBytes()));
@ -343,7 +370,7 @@ public class Transaction implements ByteSerializable, JsonSerializable {
} else if (operationId == OperationType.WORKER_CREATE_OPERATION.ordinal()) {
//TODO: Add operation deserialization support
} else if (operationId == OperationType.CUSTOM_OPERATION.ordinal()) {
//TODO: Add operation deserialization support
operation = context.deserialize(jsonOperation, CustomOperation.class);
} else if (operationId == OperationType.ASSERT_OPERATION.ordinal()) {
//TODO: Add operation deserialization support
} else if (operationId == OperationType.BALANCE_CLAIM_OPERATION.ordinal()) {

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -19,8 +19,8 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
/**
* Class that represents a graphene user account.

View File

@ -1,7 +1,22 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import com.google.common.primitives.Bytes;
import org.tukaani.xz.*;
import com.google.common.primitives.UnsignedLong;
import org.spongycastle.crypto.DataLengthException;
import org.spongycastle.crypto.InvalidCipherTextException;
import org.spongycastle.crypto.engines.AESFastEngine;
import org.spongycastle.crypto.modes.CBCBlockCipher;
import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.spongycastle.crypto.params.KeyParameter;
import org.spongycastle.crypto.params.ParametersWithIV;
import org.tukaani.xz.CorruptedInputException;
import org.tukaani.xz.FinishableOutputStream;
import org.tukaani.xz.LZMA2Options;
import org.tukaani.xz.LZMAInputStream;
import org.tukaani.xz.LZMAOutputStream;
import org.tukaani.xz.XZInputStream;
import org.tukaani.xz.XZOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -11,15 +26,10 @@ import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.spongycastle.crypto.DataLengthException;
import org.spongycastle.crypto.InvalidCipherTextException;
import org.spongycastle.crypto.engines.AESFastEngine;
import org.spongycastle.crypto.modes.CBCBlockCipher;
import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.spongycastle.crypto.params.KeyParameter;
import org.spongycastle.crypto.params.ParametersWithIV;
/**
* Class used to encapsulate common utility methods
@ -84,6 +94,26 @@ public class Util {
return buffer.array();
}
/**
* Serializes long value to a byte array.
* @param data Long value.
* @return Array of bytes.
*/
public static byte[] serializeLongToBytes(long data) {
List<Byte> bytes = new LinkedList<>();
long value = data;
do {
byte b = (byte)(value & 0x7F);
value >>= 7;
if (value != 0) {
b |= 0x80;
}
bytes.add(b);
} while (value != 0);
return Bytes.toArray(bytes);
}
/**
* Utility function that compresses data using the LZMA algorithm.
* @param inputBytes Input bytes of the data to be compressed.
@ -210,6 +240,15 @@ public class Util {
return ByteBuffer.allocate(Long.SIZE / 8).putLong(Long.reverseBytes(input)).array();
}
/**
* Same operation as in the revertInteger function, but with an UnsignedLong object as argument.
* @param input An UnsignedLong class instance
* @return The array of bytes that represent this value in the reverse format.
*/
public static byte[] revertUnsignedLong(UnsignedLong input){
return ByteBuffer.allocate(Long.SIZE / 8).putLong(Long.reverseBytes(input.longValue())).array();
}
public static byte[] revertBytes(byte[] array){
byte[] reverted = new byte[array.length];
for(int i = 0; i < reverted.length; i++){

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import java.io.DataInput;

View File

@ -1,6 +1,6 @@
package de.bitsharesmunich.graphenej;
package cy.agorise.graphenej;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.ByteSerializable;
/**
* Created by nelson on 12/5/16.

View File

@ -1,14 +1,12 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import org.w3c.dom.Node;
import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import cy.agorise.graphenej.interfaces.NodeErrorListener;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.BaseResponse;
/**
* Base class that should be extended by any implementation of a specific request to the full node.

View File

@ -1,16 +1,9 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketFrame;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import java.io.Serializable;
import java.lang.reflect.Type;
@ -18,6 +11,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_account_balances request handler.
*
@ -71,12 +72,14 @@ public class GetAccountBalances extends BaseGrapheneHandler {
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
ArrayList<Serializable> params = new ArrayList<>();
ArrayList<Serializable> assetList = new ArrayList<>();
for(Asset asset : mAssetList){
assetList.add(asset.getObjectId());
if(mAssetList != null){
for(Asset asset : mAssetList){
assetList.add(asset.getObjectId());
}
}
params.add(mUserAccount.getObjectId());
params.add(assetList);
ApiCall apiCall = new ApiCall(0, RPC.GET_ACCOUNT_BALANCES, params, RPC.VERSION, 0);
ApiCall apiCall = new ApiCall(0, RPC.GET_ACCOUNT_BALANCES, params, RPC.VERSION, requestId);
websocket.sendText(apiCall.toJsonString());
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -11,13 +11,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.AccountOptions;
import de.bitsharesmunich.graphenej.Authority;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.AccountProperties;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.AccountOptions;
import cy.agorise.graphenej.Authority;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.AccountProperties;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_account_by_name request handler.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
/**
* Created by nelson on 12/26/16.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -11,14 +11,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.AccountOptions;
import de.bitsharesmunich.graphenej.Authority;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.AccountProperties;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.AccountOptions;
import cy.agorise.graphenej.Authority;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.AccountProperties;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_accounts request handler.

View File

@ -1,13 +1,13 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketFrame;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.*;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.*;
import java.io.Serializable;
import java.lang.reflect.Type;

View File

@ -0,0 +1,112 @@
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketFrame;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.Block;
import cy.agorise.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.operations.CustomOperation;
import cy.agorise.graphenej.operations.LimitOrderCreateOperation;
import cy.agorise.graphenej.operations.TransferOperation;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GetBlock extends BaseGrapheneHandler {
private final static int LOGIN_ID = 1;
private final static int GET_DATABASE_ID = 2;
private final static int GET_BLOCK_ID = 3;
private long blockNumber;
private WitnessResponseListener mListener;
private int currentId = LOGIN_ID;
private boolean mOneTime;
public GetBlock(long blockNumber, boolean oneTime, WitnessResponseListener listener){
super(listener);
this.blockNumber = blockNumber;
this.mOneTime = oneTime;
this.mListener = listener;
}
public GetBlock(long blockNumber, WitnessResponseListener listener){
this(blockNumber, true, listener);
}
@Override
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
ArrayList<Serializable> loginParams = new ArrayList<>();
loginParams.add(null);
loginParams.add(null);
ApiCall loginCall = new ApiCall(1, RPC.CALL_LOGIN, loginParams, RPC.VERSION, currentId);
websocket.sendText(loginCall.toJsonString());
}
@Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
String response = frame.getPayloadText();
System.out.println("<<< "+response);
Gson gson = new Gson();
BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class);
if(baseResponse.error != null){
mListener.onError(baseResponse.error);
if(mOneTime){
websocket.disconnect();
}
} else {
currentId++;
ArrayList<Serializable> emptyParams = new ArrayList<>();
if (baseResponse.id == LOGIN_ID) {
ApiCall getDatabaseId = new ApiCall(1, RPC.CALL_DATABASE, emptyParams, RPC.VERSION, currentId);
websocket.sendText(getDatabaseId.toJsonString());
} else if (baseResponse.id == GET_DATABASE_ID) {
Type ApiIdResponse = new TypeToken<WitnessResponse<Integer>>() {}.getType();
WitnessResponse<Integer> witnessResponse = gson.fromJson(response, ApiIdResponse);
Integer apiId = witnessResponse.result;
ArrayList<Serializable> params = new ArrayList<>();
String blockNum = String.format("%d", this.blockNumber);
params.add(blockNum);
ApiCall loginCall = new ApiCall(apiId, RPC.CALL_GET_BLOCK, params, RPC.VERSION, currentId);
websocket.sendText(loginCall.toJsonString());
} else if (baseResponse.id == GET_BLOCK_ID) {
Type BlockResponse = new TypeToken<WitnessResponse<Block>>(){}.getType();
gson = new GsonBuilder()
.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer())
.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer())
.registerTypeAdapter(LimitOrderCreateOperation.class, new LimitOrderCreateOperation.LimitOrderCreateDeserializer())
.registerTypeAdapter(CustomOperation.class, new CustomOperation.CustomOperationDeserializer())
.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer())
.create();
WitnessResponse<Block> blockResponse = gson.fromJson(response, BlockResponse);
mListener.onSuccess(blockResponse);
if (mOneTime) {
websocket.disconnect();
}
}
}
}
@Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
if(frame.isTextFrame())
System.out.println(">>> "+frame.getPayloadText());
}
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@ -11,12 +11,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.BlockHeader;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.BlockHeader;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_block_header request handler.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -11,12 +11,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.Address;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_key_references request handler.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -12,14 +12,14 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.LimitOrder;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.LimitOrder;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_limit_orders request handler.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -14,13 +14,13 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.BucketObject;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.BucketObject;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_market_history request handler.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -15,17 +15,17 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.AccountOptions;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.Authority;
import de.bitsharesmunich.graphenej.GrapheneObject;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BitAssetData;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.AccountOptions;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.Authority;
import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BitAssetData;
import cy.agorise.graphenej.models.WitnessResponse;
/**
*

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -12,16 +12,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.HistoricalTransfer;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import de.bitsharesmunich.graphenej.objects.Memo;
import de.bitsharesmunich.graphenej.operations.TransferOperation;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.HistoricalTransfer;
import cy.agorise.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.objects.Memo;
import cy.agorise.graphenej.operations.TransferOperation;
/**
* Class used to encapsulate the communication sequence used to retrieve the transaction history of

View File

@ -1,20 +1,19 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.WitnessResponse;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFrame;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.BaseOperation;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.BaseOperation;
import java.io.Serializable;
import java.lang.reflect.Type;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -11,11 +11,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.MarketTrade;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.MarketTrade;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements get_trade_history request handler.

View File

@ -1,14 +1,14 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketFrame;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
import java.io.Serializable;
import java.lang.reflect.Type;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -11,11 +11,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements lookup_accounts request handler.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@ -11,11 +11,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that implements lookup_asset_symbols request handler.
@ -28,7 +28,7 @@ import de.bitsharesmunich.graphenej.models.WitnessResponse;
*/
public class LookupAssetSymbols extends BaseGrapheneHandler {
private WitnessResponseListener mListener;
private List<Asset> assets;
private List<? extends Object> assets;
private boolean mOneTime;
@ -42,7 +42,7 @@ public class LookupAssetSymbols extends BaseGrapheneHandler {
* be implemented by the party interested in being notified about the
* success/failure of the operation.
*/
public LookupAssetSymbols(List<Asset> assets, boolean oneTime, WitnessResponseListener listener){
public LookupAssetSymbols(List<? extends Object> assets, boolean oneTime, WitnessResponseListener listener){
super(listener);
this.assets = assets;
this.mOneTime = oneTime;
@ -57,7 +57,7 @@ public class LookupAssetSymbols extends BaseGrapheneHandler {
* be implemented by the party interested in being notified about the
* success/failure of the operation.
*/
public LookupAssetSymbols(List<Asset> assets, WitnessResponseListener listener){
public LookupAssetSymbols(List<Object> assets, WitnessResponseListener listener){
this(assets, true, listener);
}
@ -65,8 +65,13 @@ public class LookupAssetSymbols extends BaseGrapheneHandler {
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
ArrayList<Serializable> params = new ArrayList<>();
ArrayList<String> subArray = new ArrayList<>();
for(Asset asset : this.assets){
subArray.add(asset.getObjectId());
for(int i = 0; i < assets.size(); i++){
Object obj = assets.get(i);
if(obj instanceof String){
subArray.add((String) obj);
}else{
subArray.add(((Asset) obj).getObjectId());
}
params.add(subArray);
}
ApiCall loginCall = new ApiCall(0, RPC.CALL_LOOKUP_ASSET_SYMBOLS, params, RPC.VERSION, 0);

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -13,22 +13,22 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.Transaction;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.errors.RepeatedRequestIdException;
import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener;
import de.bitsharesmunich.graphenej.interfaces.SubscriptionHub;
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.DynamicGlobalProperties;
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import de.bitsharesmunich.graphenej.objects.Memo;
import de.bitsharesmunich.graphenej.operations.LimitOrderCreateOperation;
import de.bitsharesmunich.graphenej.operations.TransferOperation;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.errors.RepeatedRequestIdException;
import cy.agorise.graphenej.interfaces.NodeErrorListener;
import cy.agorise.graphenej.interfaces.SubscriptionHub;
import cy.agorise.graphenej.interfaces.SubscriptionListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.DynamicGlobalProperties;
import cy.agorise.graphenej.models.SubscriptionResponse;
import cy.agorise.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.objects.Memo;
import cy.agorise.graphenej.operations.CustomOperation;
import cy.agorise.graphenej.operations.LimitOrderCreateOperation;
import cy.agorise.graphenej.operations.TransferOperation;
/**
* A WebSocket adapter prepared to be used as a basic dispatch hub for subscription messages.
@ -60,6 +60,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
private int databaseApiId = -1;
private int subscriptionCounter = 0;
private HashMap<Long, BaseGrapheneHandler> mHandlerMap = new HashMap<>();
private List<BaseGrapheneHandler> pendingHandlerList = new ArrayList<>();
// State variables
private boolean isUnsubscribing;
@ -89,6 +90,7 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
builder.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer());
builder.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer());
builder.registerTypeAdapter(LimitOrderCreateOperation.class, new LimitOrderCreateOperation.LimitOrderCreateDeserializer());
builder.registerTypeAdapter(CustomOperation.class, new CustomOperation.CustomOperationDeserializer());
builder.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer());
builder.registerTypeAdapter(UserAccount.class, new UserAccount.UserAccountSimpleDeserializer());
builder.registerTypeAdapter(DynamicGlobalProperties.class, new DynamicGlobalProperties.DynamicGlobalPropertiesDeserializer());
@ -141,17 +143,29 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
String message = frame.getPayloadText();
System.out.println("<< "+message);
if(currentId == LOGIN_ID){
currentId = GET_DATABASE_ID;
ArrayList<Serializable> emptyParams = new ArrayList<>();
ApiCall getDatabaseId = new ApiCall(1, RPC.CALL_DATABASE, emptyParams, RPC.VERSION, currentId);
websocket.sendText(getDatabaseId.toJsonString());
currentId++;
}else if(currentId == GET_DATABASE_ID){
Type ApiIdResponse = new TypeToken<WitnessResponse<Integer>>() {}.getType();
WitnessResponse<Integer> witnessResponse = gson.fromJson(message, ApiIdResponse);
databaseApiId = witnessResponse.result;
subscribe();
} else if(currentId == SUBSCRIPTION_REQUEST){
// Subscribing only if the clearFilter parameter is true
if(clearFilter){
subscribe();
}
// Dispatching the onConnected event to every pending handler
if(pendingHandlerList.size() > 0){
for(BaseGrapheneHandler handler : pendingHandlerList){
handler.setRequestId(++currentId);
dispatchConnectionEvent(handler);
}
pendingHandlerList.clear();
}
} else if(currentId >= SUBSCRIPTION_REQUEST){
List<SubscriptionListener> subscriptionListeners = mSubscriptionDeserializer.getSubscriptionListeners();
if(!isUnsubscribing){
@ -205,12 +219,12 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
private void subscribe(){
isUnsubscribing = false;
currentId++;
ArrayList<Serializable> subscriptionParams = new ArrayList<>();
subscriptionParams.add(String.format("%d", SUBSCRIPTION_NOTIFICATION));
subscriptionParams.add(clearFilter);
ApiCall getDatabaseId = new ApiCall(databaseApiId, RPC.CALL_SET_SUBSCRIBE_CALLBACK, subscriptionParams, RPC.VERSION, SUBSCRIPTION_REQUEST);
ApiCall getDatabaseId = new ApiCall(databaseApiId, RPC.CALL_SET_SUBSCRIBE_CALLBACK, subscriptionParams, RPC.VERSION, currentId);
mWebsocket.sendText(getDatabaseId.toJsonString());
currentId = SUBSCRIPTION_REQUEST;
}
/**
@ -236,7 +250,8 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
isSubscribed = false;
isUnsubscribing = true;
ApiCall unsubscribe = new ApiCall(databaseApiId, RPC.CALL_CANCEL_ALL_SUBSCRIPTIONS, new ArrayList<Serializable>(), RPC.VERSION, SUBSCRIPTION_REQUEST);
currentId++;
ApiCall unsubscribe = new ApiCall(databaseApiId, RPC.CALL_CANCEL_ALL_SUBSCRIPTIONS, new ArrayList<Serializable>(), RPC.VERSION, currentId);
mWebsocket.sendText(unsubscribe.toJsonString());
// Clearing all subscription listeners
@ -264,13 +279,26 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
subscriptionCounter = 0;
}
public void addRequestHandler(BaseGrapheneHandler handler) throws RepeatedRequestIdException {
if(mHandlerMap.get(handler.getRequestId()) != null){
throw new RepeatedRequestIdException("Already registered handler with id: "+handler.getRequestId());
/**
* Adds a handler either to the map of handlers or to a list of pending ones
* @param handler The handler of a given request
* @throws RepeatedRequestIdException
*/
public void addRequestHandler(BaseGrapheneHandler handler) {
if(mWebsocket != null && currentId > SUBSCRIPTION_REQUEST){
handler.setRequestId(++currentId);
mHandlerMap.put(handler.getRequestId(), handler);
dispatchConnectionEvent(handler);
}else{
pendingHandlerList.add(handler);
}
}
mHandlerMap.put(handler.getRequestId(), handler);
/**
* Informing a handler that we have a connection with the full node.
* @param handler Handler that should be notified.
*/
private void dispatchConnectionEvent(BaseGrapheneHandler handler){
try {
// Artificially calling the 'onConnected' method of the handler.
// The underlying websocket was already connected, but from the WebSocketAdapter
@ -279,6 +307,13 @@ public class SubscriptionMessagesHub extends BaseGrapheneHandler implements Subs
} catch (Exception e) {
System.out.println("Exception. Msg: "+e.getMessage());
System.out.println("Exception type: "+e);
for(StackTraceElement el : e.getStackTrace()){
System.out.println(String.format("at %s.%s(%s:%s)",
el.getClassName(),
el.getMethodName(),
el.getFileName(),
el.getLineNumber()));
}
}
}
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api;
package cy.agorise.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -13,16 +13,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import de.bitsharesmunich.graphenej.Asset;
import de.bitsharesmunich.graphenej.AssetAmount;
import de.bitsharesmunich.graphenej.BlockData;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.Transaction;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.ApiCall;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.DynamicGlobalProperties;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.Asset;
import cy.agorise.graphenej.AssetAmount;
import cy.agorise.graphenej.BlockData;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.ApiCall;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.DynamicGlobalProperties;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class that will handle the transaction publication procedure.

View File

@ -1,14 +1,13 @@
package de.bitsharesmunich.graphenej.api.android;
package cy.agorise.graphenej.api.android;
import java.util.ArrayList;
import java.util.List;
import de.bitsharesmunich.graphenej.api.BaseGrapheneHandler;
import de.bitsharesmunich.graphenej.api.SubscriptionMessagesHub;
import de.bitsharesmunich.graphenej.errors.RepeatedRequestIdException;
import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import cy.agorise.graphenej.api.BaseGrapheneHandler;
import cy.agorise.graphenej.api.SubscriptionMessagesHub;
import cy.agorise.graphenej.errors.RepeatedRequestIdException;
import cy.agorise.graphenej.interfaces.NodeErrorListener;
import cy.agorise.graphenej.models.BaseResponse;
/**
* Class used to encapsulate all connections that should be done to a node (with node hop support).
@ -17,10 +16,12 @@ import de.bitsharesmunich.graphenej.models.BaseResponse;
* be used as a singleton under an application.
*/
public class NodeConnection {
/**
* List of URLs of the nodes
*/
private List<String> mUrlList;
/**
* Index of the current node from the list
*/
@ -28,8 +29,11 @@ public class NodeConnection {
private WebsocketWorkerThread mThread;
private SubscriptionMessagesHub mMessagesHub;
private long requestCounter = SubscriptionMessagesHub.MANUAL_SUBSCRIPTION_ID + 1;
private WitnessResponseListener mErrorListener;
private NodeErrorListener mErrorListener;
/**
* Singleton instance
*/
private static NodeConnection instance;
private String mUser;
@ -56,7 +60,6 @@ public class NodeConnection {
* @param url: URL of the node
*/
public void addNodeUrl(String url){
System.out.println("addNodeUrl: "+url);
this.mUrlList.add(url);
}
@ -67,8 +70,7 @@ public class NodeConnection {
* @param urlList: List of URLs of the nodes
*/
public void addNodeUrls(List<String> urlList){
List<String> newList = new ArrayList<String>(mUrlList);
newList.addAll(urlList);
mUrlList.addAll(urlList);
}
/**
@ -91,7 +93,7 @@ public class NodeConnection {
@Override
public void onError(BaseResponse.Error error) {
System.out.println("NodeConnect Error. Msg: "+error);
mUrlIndex++;
connect(mUser, mPassword, mSubscribe, mErrorListener);
}
};
@ -113,19 +115,24 @@ public class NodeConnection {
* should be implemented by the party interested in being notified
* about the failure of the desired broadcast operation.
*/
public void connect(String user, String password, boolean subscribe, WitnessResponseListener errorListener) {
if(this.mUrlList.size() > 0){
mUser = user;
mPassword = password;
mSubscribe = subscribe;
System.out.println("Connecting to: "+ this.mUrlList.get(mUrlIndex));
mErrorListener = errorListener;
mThread = new WebsocketWorkerThread(this.mUrlList.get(mUrlIndex), mInternalErrorListener);
mUrlIndex = mUrlIndex + 1 % this.mUrlList.size();
public void connect(String user, String password, boolean subscribe, NodeErrorListener errorListener) {
if(mUrlList.size() > 0){
if(mUrlIndex < mUrlList.size()){
System.out.println("Connecting to: "+ this.mUrlList.get(mUrlIndex));
mUser = user;
mPassword = password;
mSubscribe = subscribe;
mErrorListener = errorListener;
mThread = new WebsocketWorkerThread(this.mUrlList.get(mUrlIndex), mInternalErrorListener);
mMessagesHub = new SubscriptionMessagesHub(user, password, subscribe, mInternalErrorListener);
mThread.addListener(mMessagesHub);
mThread.start();
mMessagesHub = new SubscriptionMessagesHub(user, password, subscribe, mInternalErrorListener);
mThread.addListener(mMessagesHub);
mThread.start();
}else{
errorListener.onError(new BaseResponse.Error("Can't connect, ran out of URLs!"));
}
}else{
errorListener.onError(new BaseResponse.Error("Can't connect, missing URL"));
}
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.api.android;
package cy.agorise.graphenej.api.android;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketException;
@ -10,9 +10,9 @@ import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import de.bitsharesmunich.graphenej.interfaces.NodeErrorListener;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.test.NaiveSSLContext;
import cy.agorise.graphenej.interfaces.NodeErrorListener;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.test.NaiveSSLContext;
/**
* Class used to encapsulate the thread where the WebSocket does the requests.
@ -63,6 +63,7 @@ public class WebsocketWorkerThread extends Thread {
* about the failure of the connection.
*/
public WebsocketWorkerThread(String url, NodeErrorListener errorListener){
mErrorListener = errorListener;
try {
WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(TIMEOUT);
@ -74,13 +75,18 @@ public class WebsocketWorkerThread extends Thread {
}
mWebSocket = factory.createSocket(url);
mErrorListener = errorListener;
} catch (IOException e) {
System.out.println("IOException. Msg: "+e.getMessage());
mErrorListener.onError(new BaseResponse.Error(e.getMessage()));
} catch(NullPointerException e){
System.out.println("NullPointerException at WebsocketWorkerThreas. Msg: "+e.getMessage());
mErrorListener.onError(new BaseResponse.Error(e.getMessage()));
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
mErrorListener.onError(new BaseResponse.Error(e.getMessage()));
} catch(IllegalArgumentException e){
System.out.println("IllegalArgumentException. Msg: "+e.getMessage());
mErrorListener.onError(new BaseResponse.Error(e.getMessage()));
}
}

View File

@ -32,7 +32,7 @@
* fitness for a particular purpose and non-infringement.
*/
package de.bitsharesmunich.graphenej.crypto;
package cy.agorise.graphenej.crypto;
import java.io.DataInputStream;
import java.io.File;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.crypto;
package cy.agorise.graphenej.crypto;
import java.nio.ByteBuffer;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.bitsharesmunich.graphenej.crypto;
package cy.agorise.graphenej.crypto;
public interface RandomSource {
/**

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.crypto;
package cy.agorise.graphenej.crypto;
import java.security.SecureRandom;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.crypto;
package cy.agorise.graphenej.crypto;
import java.nio.ByteBuffer;
import java.security.DigestException;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.errors;
package cy.agorise.graphenej.errors;
/**
* Created by nelson on 12/20/16.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.errors;
package cy.agorise.graphenej.errors;
/**
* Created by nelson on 1/18/17.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.errors;
package cy.agorise.graphenej.errors;
/**
* Created by nelson on 12/25/16.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.errors;
package cy.agorise.graphenej.errors;
/**
* Created by nelson on 12/1/16.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.errors;
package cy.agorise.graphenej.errors;
/**
* Created by nelson on 3/1/17.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.errors;
package cy.agorise.graphenej.errors;
/**
* Created by nelson on 11/14/16.

View File

@ -0,0 +1,14 @@
package cy.agorise.graphenej.errors;
import cy.agorise.graphenej.api.BaseGrapheneHandler;
/**
* Thrown by the {@link cy.agorise.graphenej.api.SubscriptionMessagesHub#addRequestHandler(BaseGrapheneHandler)}
* whenever the user tries to register a new handler with a previously registered id
*/
public class RepeatedRequestIdException extends Exception {
public RepeatedRequestIdException(String message){
super(message);
}
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
/**
* Interface implemented by all entities for which makes sense to have a byte-array representation.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
/**
* Interface used to group both ByteSerializable and JsonSerializable interfaces.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
import com.google.gson.JsonElement;

View File

@ -1,6 +1,6 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.BaseResponse;
/**
* Interface to be implemented by any listener to network errors.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
import java.util.List;

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
import de.bitsharesmunich.graphenej.ObjectType;
import de.bitsharesmunich.graphenej.models.SubscriptionResponse;
import cy.agorise.graphenej.ObjectType;
import cy.agorise.graphenej.models.SubscriptionResponse;
/**
* Generic interface that must be implemented by any class that wants to be informed about a specific

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.interfaces;
package cy.agorise.graphenej.interfaces;
import de.bitsharesmunich.graphenej.models.BaseResponse;
import de.bitsharesmunich.graphenej.models.WitnessResponse;
import cy.agorise.graphenej.models.BaseResponse;
import cy.agorise.graphenej.models.WitnessResponse;
/**
* Class used to represent any listener to network requests.

View File

@ -1,8 +1,8 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import java.io.Serializable;
import de.bitsharesmunich.graphenej.GrapheneObject;
import cy.agorise.graphenej.GrapheneObject;
/**
* Created by nelson on 1/12/17.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import de.bitsharesmunich.graphenej.AccountOptions;
import de.bitsharesmunich.graphenej.Authority;
import cy.agorise.graphenej.AccountOptions;
import cy.agorise.graphenej.Authority;
/**
* Created by nelson on 11/15/16.

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
@ -6,13 +6,14 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import cy.agorise.graphenej.interfaces.JsonSerializable;
/**
* Class used to build a Graphene websocket API call.
* @see <a href="http://docs.bitshares.org/api/websocket.html">Websocket Calls & Notifications</a>
@ -28,9 +29,9 @@ public class ApiCall implements JsonSerializable {
public String jsonrpc;
public List<Serializable> params;
public int apiId;
public int sequenceId;
public long sequenceId;
public ApiCall(int apiId, String methodToCall, List<Serializable> params, String jsonrpc, int sequenceId){
public ApiCall(int apiId, String methodToCall, List<Serializable> params, String jsonrpc, long sequenceId){
this.apiId = apiId;
this.method = "call";
this.methodToCall = methodToCall;
@ -39,7 +40,7 @@ public class ApiCall implements JsonSerializable {
this.sequenceId = sequenceId;
}
public ApiCall(int apiId, String method, String methodToCall, List<Serializable> params, String jsonrpc, int sequenceId){
public ApiCall(int apiId, String method, String methodToCall, List<Serializable> params, String jsonrpc, long sequenceId){
this.apiId = apiId;
this.method = method;
this.methodToCall = methodToCall;

View File

@ -1,6 +1,6 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import de.bitsharesmunich.graphenej.Price;
import cy.agorise.graphenej.Price;
/**
* Created by nelson on 1/9/17.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import com.google.gson.*;
import de.bitsharesmunich.graphenej.Asset;
import cy.agorise.graphenej.Asset;
import java.lang.reflect.Type;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
/**
* Created by nelson on 11/12/16.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import de.bitsharesmunich.graphenej.GrapheneObject;
import de.bitsharesmunich.graphenej.Price;
import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.Price;
/**
* This is the representation of the response from the 'get_objects' call with

View File

@ -0,0 +1,71 @@
package cy.agorise.graphenej.models;
import cy.agorise.graphenej.Transaction;
import java.util.List;
public class Block {
private String previous;
private String timestamp;
private String witness;
private String transaction_merkle_root;
private Object[] extensions;
private String witness_signature;
private List<Transaction> transactions;
public String getPrevious() {
return previous;
}
public void setPrevious(String previous) {
this.previous = previous;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public String getWitness() {
return witness;
}
public void setWitness(String witness) {
this.witness = witness;
}
public String getTransaction_merkle_root() {
return transaction_merkle_root;
}
public void setTransaction_merkle_root(String transaction_merkle_root) {
this.transaction_merkle_root = transaction_merkle_root;
}
public Object[] getExtensions() {
return extensions;
}
public void setExtensions(Object[] extensions) {
this.extensions = extensions;
}
public String getWitness_signature() {
return witness_signature;
}
public void setWitness_signature(String witness_signature) {
this.witness_signature = witness_signature;
}
public List<Transaction> getTransactions() {
return transactions;
}
public void setTransactions(List<Transaction> transactions) {
this.transactions = transactions;
}
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
/**
* Created by nelson on 12/13/16.

View File

@ -1,14 +1,9 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import de.bitsharesmunich.graphenej.GrapheneObject;
import de.bitsharesmunich.graphenej.Transaction;
import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.Transaction;
import java.io.Serializable;
import java.lang.reflect.Type;
/**
* Created by nelson on 1/28/17.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import com.google.gson.*;
import de.bitsharesmunich.graphenej.Asset;
import cy.agorise.graphenej.Asset;
import java.lang.reflect.Type;
import java.math.BigDecimal;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
@ -13,8 +13,8 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import de.bitsharesmunich.graphenej.GrapheneObject;
import de.bitsharesmunich.graphenej.Util;
import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.Util;
/**
* Class used to deserialize the 'result' field returned by the full node after making a call

View File

@ -1,6 +1,6 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import de.bitsharesmunich.graphenej.operations.TransferOperation;
import cy.agorise.graphenej.operations.TransferOperation;
/**

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
@ -14,10 +14,10 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import de.bitsharesmunich.graphenej.GrapheneObject;
import de.bitsharesmunich.graphenej.ObjectType;
import de.bitsharesmunich.graphenej.Transaction;
import de.bitsharesmunich.graphenej.interfaces.SubscriptionListener;
import cy.agorise.graphenej.GrapheneObject;
import cy.agorise.graphenej.ObjectType;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.interfaces.SubscriptionListener;
/**
* Class that represents a generic subscription response.
@ -111,13 +111,15 @@ public class SubscriptionResponse {
* to be removed from the list.
*/
public void removeSubscriptionListener(SubscriptionListener subscriptionListener){
int currentCount = listenerTypeCount.get(subscriptionListener.getInterestObjectType());
if(currentCount != 0){
this.listenerTypeCount.put(subscriptionListener.getInterestObjectType(), currentCount);
}else{
System.out.println("Trying to remove subscription listener, but none is registered!");
if(listenerTypeCount.containsKey(subscriptionListener.getInterestObjectType())){
int currentCount = listenerTypeCount.get(subscriptionListener.getInterestObjectType());
if(currentCount > 0){
this.listenerTypeCount.put(subscriptionListener.getInterestObjectType(), currentCount - 1);
this.mListeners.remove(subscriptionListener);
}else{
System.out.println("Trying to remove subscription listener, but none is registered!");
}
}
this.mListeners.remove(subscriptionListener);
}
/**

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models;
package cy.agorise.graphenej.models;
/**
* Generic witness response

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models.backup;
package cy.agorise.graphenej.models.backup;
/**
* Class used to represent an entry in the "linked_accounts" field of the JSON-formatted backup file.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.models.backup;
package cy.agorise.graphenej.models.backup;
import de.bitsharesmunich.graphenej.Address;
import de.bitsharesmunich.graphenej.Util;
import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.Util;
import org.bitcoinj.core.ECKey;
/**

View File

@ -1,11 +1,10 @@
package de.bitsharesmunich.graphenej.models.backup;
package cy.agorise.graphenej.models.backup;
import de.bitsharesmunich.graphenej.Address;
import de.bitsharesmunich.graphenej.Util;
import de.bitsharesmunich.graphenej.crypto.SecureRandomGenerator;
import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.Util;
import cy.agorise.graphenej.crypto.SecureRandomGenerator;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Sha256Hash;
import org.spongycastle.crypto.digests.SHA256Digest;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.models.backup;
package cy.agorise.graphenej.models.backup;
import java.util.List;

View File

@ -1,31 +1,35 @@
package de.bitsharesmunich.graphenej.objects;
package cy.agorise.graphenej.objects;
import com.google.common.primitives.Bytes;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import de.bitsharesmunich.graphenej.Address;
import de.bitsharesmunich.graphenej.PublicKey;
import de.bitsharesmunich.graphenej.Util;
import de.bitsharesmunich.graphenej.errors.ChecksumException;
import de.bitsharesmunich.graphenej.errors.MalformedAddressException;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import de.bitsharesmunich.graphenej.operations.TransferOperation;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.bitcoinj.core.ECKey;
import org.spongycastle.math.ec.ECPoint;
import java.lang.reflect.Type;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import cy.agorise.graphenej.Address;
import cy.agorise.graphenej.PublicKey;
import cy.agorise.graphenej.Util;
import cy.agorise.graphenej.errors.ChecksumException;
import cy.agorise.graphenej.errors.MalformedAddressException;
import cy.agorise.graphenej.interfaces.ByteSerializable;
import cy.agorise.graphenej.interfaces.JsonSerializable;
/**
* Created by nelson on 11/9/16.
* Class used to represent a memo data structure
* {@url https://bitshares.org/doxygen/structgraphene_1_1chain_1_1memo__data.html}
*/
public class Memo implements ByteSerializable, JsonSerializable {
public final static String TAG = "Memo";
@ -36,7 +40,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
private Address from;
private Address to;
private long nonce;
private BigInteger nonce;
private byte[] message;
private String plaintextMessage;
@ -67,7 +71,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
* @param nonce: Nonce used in the encryption.
* @param message: Message in ciphertext.
*/
public Memo(Address from, Address to, long nonce, byte[] message){
public Memo(Address from, Address to, BigInteger nonce, byte[] message){
this.from = from;
this.to = to;
this.nonce = nonce;
@ -90,7 +94,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
return this.to;
}
public long getNonce(){
public BigInteger getNonce(){
return this.nonce;
}
@ -113,14 +117,14 @@ public class Memo implements ByteSerializable, JsonSerializable {
* @param message: Plaintext message.
* @return: The encrypted version of the message.
*/
public static byte[] encryptMessage(ECKey privateKey, PublicKey publicKey, long nonce, String message){
public static byte[] encryptMessage(ECKey privateKey, PublicKey publicKey, BigInteger nonce, String message){
byte[] encrypted = null;
try {
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
// Getting nonce bytes
String stringNonce = String.format("%d", nonce);
String stringNonce = nonce.toString();
byte[] nonceBytes = Arrays.copyOfRange(Util.hexlify(stringNonce), 0, stringNonce.length());
// Getting shared secret
@ -154,7 +158,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
* @param message: Plaintext message.
* @return: The encrypted version of the message.
*/
public static byte[] encryptMessage(ECKey privateKey, Address destinationAddress, long nonce, String message){
public static byte[] encryptMessage(ECKey privateKey, Address destinationAddress, BigInteger nonce, String message){
return encryptMessage(privateKey, destinationAddress.getPublicKey(), nonce, message);
}
@ -168,14 +172,14 @@ public class Memo implements ByteSerializable, JsonSerializable {
* @return: The plaintext version of the enrcrypted message.
* @throws ChecksumException
*/
public static String decryptMessage(ECKey privateKey, PublicKey publicKey, long nonce, byte[] message) throws ChecksumException {
public static String decryptMessage(ECKey privateKey, PublicKey publicKey, BigInteger nonce, byte[] message) throws ChecksumException {
String plaintext = "";
try {
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
// Getting nonce bytes
String stringNonce = String.format("%d", nonce);
String stringNonce = nonce.toString();
byte[] nonceBytes = Arrays.copyOfRange(Util.hexlify(stringNonce), 0, stringNonce.length());
// Getting shared secret
@ -215,7 +219,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
* @return: The plaintext version of the enrcrypted message.
* @throws ChecksumException
*/
public static String decryptMessage(ECKey privateKey, Address sourceAddress, long nonce, byte[] message) throws ChecksumException {
public static String decryptMessage(ECKey privateKey, Address sourceAddress, BigInteger nonce, byte[] message) throws ChecksumException {
return decryptMessage(privateKey, sourceAddress.getPublicKey(), nonce, message);
}
@ -236,7 +240,12 @@ public class Memo implements ByteSerializable, JsonSerializable {
new byte[]{(byte) this.message.length},
this.message);
} else {
byte[] nonceBytes = Util.revertLong(nonce);
byte[] paddedNonceBytes = new byte[8];
byte[] originalNonceBytes = nonce.toByteArray();
System.arraycopy(originalNonceBytes, 0, paddedNonceBytes, 8 - originalNonceBytes.length, originalNonceBytes.length);
byte[] nonceBytes = Util.revertBytes(paddedNonceBytes);
// byte[] nonceBytes = Util.revertBytes(nonce.toByteArray());
ECPoint senderPoint = ECKey.compressPoint(from.getPublicKey().getKey().getPubKeyPoint());
PublicKey senderPublicKey = new PublicKey(ECKey.fromPublicOnly(senderPoint));
@ -253,31 +262,62 @@ public class Memo implements ByteSerializable, JsonSerializable {
}
}
/**
* Converts a memo instance to a String.
*
* The nonce is always encoded as a decimal number in a string field.
* @return
*/
@Override
public String toJsonString() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
Gson gson = new Gson();
return gson.toJson(toJson(true));
}
/**
* Converts a memo instance into a JsonElement.
*
* This method differs from the {@link #toJson(boolean)} in that here the nonce is encoded as an
* hexadecimal number, while in that one we offer the user to choose either the decimal or hexadecimal
* representations.
*
* @return JsonObject instance representing this memo
*/
@Override
public JsonElement toJsonObject() {
JsonObject memoObject = new JsonObject();
if ((this.from == null) && (this.to == null)) {
// Public memo
// TODO: Add public memo support
// memoObject.addProperty(KEY_FROM, "");
// memoObject.addProperty(KEY_TO, "");
// memoObject.addProperty(KEY_NONCE, "");
// memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
// TODO: Check if this public memo serialization is accepted
memoObject.addProperty(KEY_FROM, "");
memoObject.addProperty(KEY_TO, "");
memoObject.addProperty(KEY_NONCE, "");
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
return null;
}else{
memoObject.addProperty(KEY_FROM, this.from.toString());
memoObject.addProperty(KEY_TO, this.to.toString());
memoObject.addProperty(KEY_NONCE, String.format("%d", this.nonce));
memoObject.addProperty(KEY_NONCE, String.format("%x", this.nonce));
memoObject.addProperty(KEY_MESSAGE, Util.bytesToHex(this.message));
}
return memoObject;
}
/**
* Method that converts the memo into a JsonObject.
*
* @param decimal If true, the nonce is saved as string containing a decimal number representation.
* @return JsonObject instance representing this memo
*/
public JsonElement toJson(boolean decimal){
JsonElement jsonElement = toJsonObject();
if(decimal){
JsonObject jsonObject = (JsonObject) jsonElement;
BigInteger nonce = new BigInteger(jsonObject.get(KEY_NONCE).getAsString(), 16);
jsonObject.addProperty(KEY_NONCE, nonce.toString());
}
return jsonElement;
}
/**
* Class used to deserialize a memo
*/
@ -288,14 +328,19 @@ public class Memo implements ByteSerializable, JsonSerializable {
JsonObject jsonObject = json.getAsJsonObject();
String fromAddress = jsonObject.get(KEY_FROM).getAsString();
String toAddress = jsonObject.get(KEY_TO).getAsString();
long nonce = jsonObject.get(KEY_NONCE).getAsLong();
String msg = jsonObject.get(KEY_MESSAGE).getAsString();
// Apparently the nonce is always coming from the full node as a string containing a
// decimal number. This is at odds with the result of the #toJsonObject method
// which encodes this data in hexadecimal.
BigInteger nonce = new BigInteger(jsonObject.get(KEY_NONCE).getAsString(), 10);
String msg = jsonObject.get(KEY_MESSAGE).getAsString();
Memo memo = null;
try{
Address from = new Address(fromAddress);
Address to = new Address(toAddress);
byte[] message = Util.hexToBytes(msg);
memo = new Memo(from, to, nonce, message);
}catch(MalformedAddressException e){
System.out.println("MalformedAddressException. Msg: "+e.getMessage());
@ -303,4 +348,15 @@ public class Memo implements ByteSerializable, JsonSerializable {
return memo;
}
}
}
/**
* Class used to serialize a memo
*/
public static class MemoSerializer implements JsonSerializer<Memo> {
@Override
public JsonElement serialize(Memo memo, Type typeOfSrc, JsonSerializationContext context) {
return memo.toJson(true);
}
}
}

View File

@ -1,4 +1,4 @@
package de.bitsharesmunich.graphenej.operations;
package cy.agorise.graphenej.operations;
import com.google.common.primitives.Bytes;
import com.google.common.primitives.UnsignedLong;
@ -6,7 +6,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import de.bitsharesmunich.graphenej.*;
import cy.agorise.graphenej.*;
/**
* Class used to encapsulate operations related to the ACCOUNT_UPDATE_OPERATION.

View File

@ -1,7 +1,7 @@
package de.bitsharesmunich.graphenej.operations;
package cy.agorise.graphenej.operations;
import de.bitsharesmunich.graphenej.*;
import de.bitsharesmunich.graphenej.errors.MalformedOperationException;
import cy.agorise.graphenej.*;
import cy.agorise.graphenej.errors.MalformedOperationException;
/**
* Created by nelson on 3/1/17.

View File

@ -1,6 +1,6 @@
package de.bitsharesmunich.graphenej.operations;
package cy.agorise.graphenej.operations;
import de.bitsharesmunich.graphenej.BaseOperation;
import cy.agorise.graphenej.BaseOperation;
/**
* Base template for all operation-specific factory classes.

Some files were not shown because too many files have changed in this diff Show More