diff --git a/graphenej/src/main/java/cy/agorise/graphenej/RPC.java b/graphenej/src/main/java/cy/agorise/graphenej/RPC.java index 7e2e306..d4ffc06 100644 --- a/graphenej/src/main/java/cy/agorise/graphenej/RPC.java +++ b/graphenej/src/main/java/cy/agorise/graphenej/RPC.java @@ -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"; } \ No newline at end of file diff --git a/graphenej/src/main/java/cy/agorise/graphenej/Transaction.java b/graphenej/src/main/java/cy/agorise/graphenej/Transaction.java index 5ee9df8..3ea51e3 100644 --- a/graphenej/src/main/java/cy/agorise/graphenej/Transaction.java +++ b/graphenej/src/main/java/cy/agorise/graphenej/Transaction.java @@ -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(); + } } \ No newline at end of file diff --git a/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java b/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java index a7a6b21..96dc64d 100644 --- a/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java +++ b/graphenej/src/main/java/cy/agorise/graphenej/api/android/DeserializationMap.java @@ -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){ diff --git a/graphenej/src/main/java/cy/agorise/graphenej/api/android/NetworkService.java b/graphenej/src/main/java/cy/agorise/graphenej/api/android/NetworkService.java index 6523c8b..ce9454c 100644 --- a/graphenej/src/main/java/cy/agorise/graphenej/api/android/NetworkService.java +++ b/graphenej/src/main/java/cy/agorise/graphenej/api/android/NetworkService.java @@ -546,6 +546,9 @@ public class NetworkService extends Service { }else if(responsePayloadClass == DynamicGlobalProperties.class){ Type GetDynamicGlobalPropertiesResponse = new TypeToken>(){}.getType(); parsedResponse = gson.fromJson(text, GetDynamicGlobalPropertiesResponse); + }else if(responsePayloadClass == Transaction.class){ + Type GetTransactionClass = new TypeToken>(){}.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 diff --git a/graphenej/src/main/java/cy/agorise/graphenej/api/calls/GetTransaction.java b/graphenej/src/main/java/cy/agorise/graphenej/api/calls/GetTransaction.java new file mode 100644 index 0000000..c55e2bd --- /dev/null +++ b/graphenej/src/main/java/cy/agorise/graphenej/api/calls/GetTransaction.java @@ -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 params = new ArrayList<>(); + params.add(blockNumber); + params.add(txIndex); + return new ApiCall(apiId, RPC.CALL_GET_TRANSACTION, params, RPC.VERSION, sequenceId); + } +} diff --git a/sample/src/main/java/cy/agorise/labs/sample/CallsActivity.java b/sample/src/main/java/cy/agorise/labs/sample/CallsActivity.java index c9899c8..383ec83 100644 --- a/sample/src/main/java/cy/agorise/labs/sample/CallsActivity.java +++ b/sample/src/main/java/cy/agorise/labs/sample/CallsActivity.java @@ -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 }; diff --git a/sample/src/main/java/cy/agorise/labs/sample/PerformCallActivity.java b/sample/src/main/java/cy/agorise/labs/sample/PerformCallActivity.java index 650d761..c2208b0 100644 --- a/sample/src/main/java/cy/agorise/labs/sample/PerformCallActivity.java +++ b/sample/src/main/java/cy/agorise/labs/sample/PerformCallActivity.java @@ -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: