- Added support for the "get_transaction" API call for the single-connection mode

- Overrided the toString method of the Transaction class
develop
Nelson R. Perez 2018-12-26 17:45:41 -05:00
parent 3b298ebf6b
commit 201d6957f8
7 changed files with 88 additions and 6 deletions

View File

@ -34,4 +34,5 @@ public class RPC {
public static final String CALL_GET_TRADE_HISTORY = "get_trade_history";
public static final String CALL_GET_MARKET_HISTORY = "get_market_history";
public static final String CALL_GET_ALL_ASSET_HOLDERS = "get_all_asset_holders";
public static final String CALL_GET_TRANSACTION = "get_transaction";
}

View File

@ -239,7 +239,12 @@ public class Transaction implements ByteSerializable, JsonSerializable {
// Getting the signature before anything else,
// since this might change the transaction expiration data slightly
byte[] signature = getGrapheneSignature();
byte[] signature = null;
try{
signature = getGrapheneSignature();
}catch(Exception e){
System.out.println("Could not generate signature");
}
// Formatting expiration time
Date expirationTime = new Date(blockData.getExpiration() * 1000);
@ -249,10 +254,12 @@ public class Transaction implements ByteSerializable, JsonSerializable {
// Adding expiration
obj.addProperty(KEY_EXPIRATION, dateFormat.format(expirationTime));
// Adding signatures
JsonArray signatureArray = new JsonArray();
signatureArray.add(Util.bytesToHex(signature));
obj.add(KEY_SIGNATURES, signatureArray);
if(signature != null){
// Adding signature
JsonArray signatureArray = new JsonArray();
signatureArray.add(Util.bytesToHex(signature));
obj.add(KEY_SIGNATURES, signatureArray);
}
JsonArray operationsArray = new JsonArray();
for(BaseOperation operation : operations){
@ -313,7 +320,8 @@ public class Transaction implements ByteSerializable, JsonSerializable {
SimpleDateFormat dateFormat = new SimpleDateFormat(Util.TIME_DATE_FORMAT);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
Date expirationDate = dateFormat.parse(expiration, new ParsePosition(0));
BlockData blockData = new BlockData(refBlockNum, refBlockPrefix, expirationDate.getTime());
long relativeExpiration = expirationDate.getTime() / 1000;
BlockData blockData = new BlockData(refBlockNum, refBlockPrefix, relativeExpiration);
// Parsing operation list
BaseOperation operation = null;
@ -423,4 +431,9 @@ public class Transaction implements ByteSerializable, JsonSerializable {
return new Transaction(blockData, operationList);
}
}
@Override
public String toString() {
return this.toJsonString();
}
}

View File

@ -34,6 +34,7 @@ import cy.agorise.graphenej.api.calls.GetMarketHistory;
import cy.agorise.graphenej.api.calls.GetObjects;
import cy.agorise.graphenej.api.calls.GetRelativeAccountHistory;
import cy.agorise.graphenej.api.calls.GetRequiredFees;
import cy.agorise.graphenej.api.calls.GetTransaction;
import cy.agorise.graphenej.api.calls.ListAssets;
import cy.agorise.graphenej.api.calls.LookupAssetSymbols;
import cy.agorise.graphenej.models.AccountProperties;
@ -201,6 +202,15 @@ public class DeserializationMap {
.registerTypeAdapter(Asset.class, new Asset.AssetDeserializer())
.create();
mGsonMap.put(GetAssets.class, getAssetsGson);
// GetTransaction
mClassMap.put(GetTransaction.class, Transaction.class);
Gson getTransactionGson = new GsonBuilder()
.registerTypeAdapter(Transaction.class, new Transaction.TransactionDeserializer())
.registerTypeAdapter(AssetAmount.class, new AssetAmount.AssetAmountDeserializer())
.registerTypeAdapter(TransferOperation.class, new TransferOperation.TransferDeserializer())
.create();
mGsonMap.put(GetTransaction.class, getTransactionGson);
}
public Class getReceivedClass(Class _class){

View File

@ -546,6 +546,9 @@ public class NetworkService extends Service {
}else if(responsePayloadClass == DynamicGlobalProperties.class){
Type GetDynamicGlobalPropertiesResponse = new TypeToken<JsonRpcResponse<DynamicGlobalProperties>>(){}.getType();
parsedResponse = gson.fromJson(text, GetDynamicGlobalPropertiesResponse);
}else if(responsePayloadClass == Transaction.class){
Type GetTransactionClass = new TypeToken<JsonRpcResponse<Transaction>>(){}.getType();
parsedResponse = gson.fromJson(text, GetTransactionClass);
}else if(responsePayloadClass == List.class){
// If the response payload is a List, further inquiry is required in order to
// determine a list of what is expected here

View File

@ -0,0 +1,29 @@
package cy.agorise.graphenej.api.calls;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.api.ApiAccess;
import cy.agorise.graphenej.models.ApiCall;
public class GetTransaction implements ApiCallable {
public static final int REQUIRED_API = ApiAccess.API_NONE;
private long blockNumber;
private long txIndex;
public GetTransaction(long blockNumber, long txIndex){
this.blockNumber = blockNumber;
this.txIndex = txIndex;
}
@Override
public ApiCall toApiCall(int apiId, long sequenceId) {
List<Serializable> params = new ArrayList<>();
params.add(blockNumber);
params.add(txIndex);
return new ApiCall(apiId, RPC.CALL_GET_TRANSACTION, params, RPC.VERSION, sequenceId);
}
}

View File

@ -80,6 +80,7 @@ public class CallsActivity extends AppCompatActivity {
RPC.CALL_GET_KEY_REFERENCES,
RPC.CALL_GET_ACCOUNT_BALANCES,
RPC.CALL_BROADCAST_TRANSACTION,
RPC.CALL_GET_TRANSACTION,
REMOVE_CURRENT_NODE
};

View File

@ -37,6 +37,7 @@ import cy.agorise.graphenej.OperationType;
import cy.agorise.graphenej.RPC;
import cy.agorise.graphenej.Transaction;
import cy.agorise.graphenej.UserAccount;
import cy.agorise.graphenej.Util;
import cy.agorise.graphenej.api.ConnectionStatusUpdate;
import cy.agorise.graphenej.api.android.DeserializationMap;
import cy.agorise.graphenej.api.android.RxBus;
@ -53,6 +54,7 @@ import cy.agorise.graphenej.api.calls.GetKeyReferences;
import cy.agorise.graphenej.api.calls.GetLimitOrders;
import cy.agorise.graphenej.api.calls.GetObjects;
import cy.agorise.graphenej.api.calls.GetRequiredFees;
import cy.agorise.graphenej.api.calls.GetTransaction;
import cy.agorise.graphenej.api.calls.ListAssets;
import cy.agorise.graphenej.errors.MalformedAddressException;
import cy.agorise.graphenej.models.JsonRpcResponse;
@ -169,6 +171,9 @@ public class PerformCallActivity extends ConnectedActivity {
break;
case RPC.CALL_BROADCAST_TRANSACTION:
setupBroadcastTransaction();
break;
case RPC.CALL_GET_TRANSACTION:
setupGetTransaction();
default:
Log.d(TAG,"Default called");
}
@ -315,6 +320,12 @@ public class PerformCallActivity extends ConnectedActivity {
param2.setText("1");
}
private void setupGetTransaction(){
requiredInput(2);
param1.setText("13282815");
param2.setText("0");
}
private void requiredInput(int inputCount){
if(inputCount == 0){
mParam1View.setVisibility(View.GONE);
@ -395,6 +406,9 @@ public class PerformCallActivity extends ConnectedActivity {
break;
case RPC.CALL_BROADCAST_TRANSACTION:
broadcastTransaction();
break;
case RPC.CALL_GET_TRANSACTION:
getTransaction();
default:
Log.d(TAG,"Default called");
}
@ -526,6 +540,13 @@ public class PerformCallActivity extends ConnectedActivity {
responseMap.put(id, mRPC);
}
private void getTransaction(){
long blockNum = Long.parseLong(param1.getText().toString());
long index = Long.parseLong(param2.getText().toString());
long id = mNetworkService.sendMessage(new GetTransaction(blockNum, index), GetTransaction.REQUIRED_API);
responseMap.put(id, mRPC);
}
private void broadcastTransaction(){
String destinationId = param1.getText().toString();
String amount = param2.getText().toString();
@ -564,6 +585,10 @@ public class PerformCallActivity extends ConnectedActivity {
for(AssetAmount assetAmount : balances) builder.append(assetAmount).append("\n");
mResponseView.setText(builder.toString());
break;
case RPC.CALL_GET_TRANSACTION:
Transaction tx = (Transaction) response.result;
mResponseView.setText(mResponseView.getText() + String.format("[%s][%s]", tx.toString(), Util.bytesToHex(tx.getHash())));
break;
case RPC.CALL_GET_ACCOUNTS:
case RPC.CALL_GET_BLOCK:
case RPC.CALL_GET_BLOCK_HEADER: