diff --git a/src/main/java/org/stellar/sdk/SorobanServer.java b/src/main/java/org/stellar/sdk/SorobanServer.java
index 4750891d5..cf7f46586 100644
--- a/src/main/java/org/stellar/sdk/SorobanServer.java
+++ b/src/main/java/org/stellar/sdk/SorobanServer.java
@@ -31,6 +31,7 @@
import org.stellar.sdk.requests.sorobanrpc.GetEventsRequest;
import org.stellar.sdk.requests.sorobanrpc.GetLedgerEntriesRequest;
import org.stellar.sdk.requests.sorobanrpc.GetTransactionRequest;
+import org.stellar.sdk.requests.sorobanrpc.GetTransactionsRequest;
import org.stellar.sdk.requests.sorobanrpc.SendTransactionRequest;
import org.stellar.sdk.requests.sorobanrpc.SimulateTransactionRequest;
import org.stellar.sdk.requests.sorobanrpc.SorobanRpcRequest;
@@ -41,6 +42,7 @@
import org.stellar.sdk.responses.sorobanrpc.GetLedgerEntriesResponse;
import org.stellar.sdk.responses.sorobanrpc.GetNetworkResponse;
import org.stellar.sdk.responses.sorobanrpc.GetTransactionResponse;
+import org.stellar.sdk.responses.sorobanrpc.GetTransactionsResponse;
import org.stellar.sdk.responses.sorobanrpc.SendTransactionResponse;
import org.stellar.sdk.responses.sorobanrpc.SimulateTransactionResponse;
import org.stellar.sdk.responses.sorobanrpc.SorobanRpcResponse;
@@ -160,8 +162,8 @@ public GetHealthResponse getHealth() {
* @throws RequestTimeoutException If the request timed out.
* @throws ConnectionErrorException When the request cannot be executed due to cancellation or
* connectivity problems, etc.
- * @see getHealth
- * documentation
+ * @see getFeeStats documentation
*/
public GetFeeStatsResponse getFeeStats() {
return this.sendRequest(
@@ -287,6 +289,31 @@ public GetTransactionResponse getTransaction(String hash) {
"getTransaction", params, new TypeToken>() {});
}
+ /**
+ * Gets a detailed list of transactions starting from the user specified starting point that you
+ * can paginate as long as the pages fall within the history retention of their corresponding RPC
+ * provider.
+ *
+ * @param getTransactionsRequest The {@link GetEventsRequest} to use for the request.
+ * @return A {@link GetTransactionsResponse} object containing the transactions that match the
+ * request.
+ * @throws org.stellar.sdk.exception.NetworkException All the exceptions below are subclasses of
+ * NetworkError
+ * @throws SorobanRpcException If the Soroban-RPC instance returns an error response.
+ * @throws RequestTimeoutException If the request timed out.
+ * @throws ConnectionErrorException When the request cannot be executed due to cancellation or
+ * connectivity problems, etc.
+ * @see getTransactions documentation
+ */
+ public GetTransactionsResponse getTransactions(GetTransactionsRequest getTransactionsRequest) {
+ return this.sendRequest(
+ "getTransactions",
+ getTransactionsRequest,
+ new TypeToken>() {});
+ }
+
/**
* Fetches all events that match the given {@link GetEventsRequest}.
*
diff --git a/src/main/java/org/stellar/sdk/requests/sorobanrpc/GetTransactionsRequest.java b/src/main/java/org/stellar/sdk/requests/sorobanrpc/GetTransactionsRequest.java
new file mode 100644
index 000000000..8c21dd5d9
--- /dev/null
+++ b/src/main/java/org/stellar/sdk/requests/sorobanrpc/GetTransactionsRequest.java
@@ -0,0 +1,27 @@
+package org.stellar.sdk.requests.sorobanrpc;
+
+import lombok.Builder;
+import lombok.NonNull;
+import lombok.Value;
+
+/**
+ * Request for JSON-RPC method getTransactions.
+ *
+ * @see getEvents documentation
+ */
+@Value
+@Builder(toBuilder = true)
+public class GetTransactionsRequest {
+ @NonNull Long startLedger;
+
+ PaginationOptions pagination;
+
+ @Value
+ @Builder(toBuilder = true)
+ public static class PaginationOptions {
+ Long limit;
+
+ String cursor;
+ }
+}
diff --git a/src/main/java/org/stellar/sdk/responses/sorobanrpc/GetTransactionsResponse.java b/src/main/java/org/stellar/sdk/responses/sorobanrpc/GetTransactionsResponse.java
new file mode 100644
index 000000000..d0d5e2405
--- /dev/null
+++ b/src/main/java/org/stellar/sdk/responses/sorobanrpc/GetTransactionsResponse.java
@@ -0,0 +1,96 @@
+package org.stellar.sdk.responses.sorobanrpc;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import lombok.Value;
+import org.stellar.sdk.Util;
+import org.stellar.sdk.xdr.DiagnosticEvent;
+import org.stellar.sdk.xdr.TransactionEnvelope;
+import org.stellar.sdk.xdr.TransactionMeta;
+import org.stellar.sdk.xdr.TransactionResult;
+
+/**
+ * Response for JSON-RPC method getTransactions.
+ *
+ * @see getTransactions documentation
+ */
+@Value
+public class GetTransactionsResponse {
+ List transactions;
+ Long latestLedger;
+ Long latestLedgerCloseTimestamp;
+ Long oldestLedger;
+ Long oldestLedgerCloseTimestamp;
+ String cursor;
+
+ @Value
+ public static class Transaction {
+ TransactionStatus status;
+ Integer applicationOrder;
+ Boolean feeBump;
+
+ /** The field can be parsed as {@link org.stellar.sdk.xdr.TransactionEnvelope} object. */
+ String envelopeXdr;
+
+ /** The field can be parsed as {@link org.stellar.sdk.xdr.TransactionResult} object. */
+ String resultXdr;
+
+ /** The field can be parsed as {@link org.stellar.sdk.xdr.TransactionMeta} object. */
+ String resultMetaXdr;
+
+ Long ledger;
+ Long createdAt;
+ List diagnosticEventsXdr;
+
+ /**
+ * Parses the {@code envelopeXdr} field from a string to an {@link
+ * org.stellar.sdk.xdr.TransactionEnvelope} object.
+ *
+ * @return the parsed {@link org.stellar.sdk.xdr.TransactionEnvelope} object
+ */
+ public TransactionEnvelope parseEnvelopeXdr() {
+ return Util.parseXdr(envelopeXdr, TransactionEnvelope::fromXdrBase64);
+ }
+
+ /**
+ * Parses the {@code resultXdr} field from a string to an {@link
+ * org.stellar.sdk.xdr.TransactionResult} object.
+ *
+ * @return the parsed {@link org.stellar.sdk.xdr.TransactionResult} object
+ */
+ public TransactionResult parseResultXdr() {
+ return Util.parseXdr(resultXdr, TransactionResult::fromXdrBase64);
+ }
+
+ /**
+ * Parses the {@code resultMetaXdr} field from a string to an {@link
+ * org.stellar.sdk.xdr.TransactionMeta} object.
+ *
+ * @return the parsed {@link org.stellar.sdk.xdr.TransactionMeta} object
+ */
+ public TransactionMeta parseResultMetaXdr() {
+ return Util.parseXdr(resultMetaXdr, TransactionMeta::fromXdrBase64);
+ }
+
+ /**
+ * Parses the {@code diagnosticEventsXdr} field from a list of strings to a list of {@link
+ * org.stellar.sdk.xdr.DiagnosticEvent} objects.
+ *
+ * @return a list of parsed {@link org.stellar.sdk.xdr.DiagnosticEvent} objects
+ */
+ public List parseDiagnosticEventsXdr() {
+ if (diagnosticEventsXdr == null) {
+ return null;
+ }
+ return diagnosticEventsXdr.stream()
+ .map(xdr -> Util.parseXdr(xdr, DiagnosticEvent::fromXdrBase64))
+ .collect(Collectors.toList());
+ }
+ }
+
+ public enum TransactionStatus {
+ SUCCESS,
+ FAILED
+ }
+}
diff --git a/src/test/java/org/stellar/sdk/SorobanServerTest.java b/src/test/java/org/stellar/sdk/SorobanServerTest.java
index 2e0556849..1ce434281 100644
--- a/src/test/java/org/stellar/sdk/SorobanServerTest.java
+++ b/src/test/java/org/stellar/sdk/SorobanServerTest.java
@@ -32,6 +32,7 @@
import org.stellar.sdk.requests.sorobanrpc.GetEventsRequest;
import org.stellar.sdk.requests.sorobanrpc.GetLedgerEntriesRequest;
import org.stellar.sdk.requests.sorobanrpc.GetTransactionRequest;
+import org.stellar.sdk.requests.sorobanrpc.GetTransactionsRequest;
import org.stellar.sdk.requests.sorobanrpc.SendTransactionRequest;
import org.stellar.sdk.requests.sorobanrpc.SimulateTransactionRequest;
import org.stellar.sdk.requests.sorobanrpc.SorobanRpcRequest;
@@ -41,6 +42,7 @@
import org.stellar.sdk.responses.sorobanrpc.GetLatestLedgerResponse;
import org.stellar.sdk.responses.sorobanrpc.GetLedgerEntriesResponse;
import org.stellar.sdk.responses.sorobanrpc.GetNetworkResponse;
+import org.stellar.sdk.responses.sorobanrpc.GetTransactionsResponse;
import org.stellar.sdk.responses.sorobanrpc.SendTransactionResponse;
import org.stellar.sdk.responses.sorobanrpc.SimulateTransactionResponse;
import org.stellar.sdk.xdr.ContractDataDurability;
@@ -654,6 +656,178 @@ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest)
mockWebServer.close();
}
+ @Test
+ public void testGetTransactions() throws IOException, SorobanRpcException {
+ String json =
+ "{\n"
+ + " \"jsonrpc\": \"2.0\",\n"
+ + " \"id\": \"198cb1a8-9104-4446-a269-88bf000c2721\",\n"
+ + " \"result\": {\n"
+ + " \"transactions\": [\n"
+ + " {\n"
+ + " \"status\": \"FAILED\",\n"
+ + " \"applicationOrder\": 1,\n"
+ + " \"feeBump\": false,\n"
+ + " \"envelopeXdr\": \"AAAAAgAAAACDz21Q3CTITlGqRus3/96/05EDivbtfJncNQKt64BTbAAAASwAAKkyAAXlMwAAAAEAAAAAAAAAAAAAAABmWeASAAAAAQAAABR3YWxsZXQ6MTcxMjkwNjMzNjUxMAAAAAEAAAABAAAAAIPPbVDcJMhOUapG6zf/3r/TkQOK9u18mdw1Aq3rgFNsAAAAAQAAAABwOSvou8mtwTtCkysVioO35TSgyRir2+WGqO8FShG/GAAAAAFVQUgAAAAAAO371tlrHUfK+AvmQvHje1jSUrvJb3y3wrJ7EplQeqTkAAAAAAX14QAAAAAAAAAAAeuAU2wAAABAn+6A+xXvMasptAm9BEJwf5Y9CLLQtV44TsNqS8ocPmn4n8Rtyb09SBiFoMv8isYgeQU5nAHsIwBNbEKCerusAQ==\",\n"
+ + " \"resultXdr\": \"AAAAAAAAAGT/////AAAAAQAAAAAAAAAB////+gAAAAA=\",\n"
+ + " \"resultMetaXdr\": \"AAAAAwAAAAAAAAACAAAAAwAc0RsAAAAAAAAAAIPPbVDcJMhOUapG6zf/3r/TkQOK9u18mdw1Aq3rgFNsAAAAF0YpYBQAAKkyAAXlMgAAAAsAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAABzRGgAAAABmWd/VAAAAAAAAAAEAHNEbAAAAAAAAAACDz21Q3CTITlGqRus3/96/05EDivbtfJncNQKt64BTbAAAABdGKWAUAACpMgAF5TMAAAALAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAc0RsAAAAAZlnf2gAAAAAAAAAAAAAAAAAAAAA=\",\n"
+ + " \"ledger\": 1888539,\n"
+ + " \"createdAt\": 1717166042\n"
+ + " },\n"
+ + " {\n"
+ + " \"status\": \"SUCCESS\",\n"
+ + " \"applicationOrder\": 2,\n"
+ + " \"feeBump\": false,\n"
+ + " \"envelopeXdr\": \"AAAAAgAAAAC4EZup+ewCs/doS3hKbeAa4EviBHqAFYM09oHuLtqrGAAPQkAAGgQZAAAANgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAABB90WssODNIgi6BHveqzxTRmIpvAFRyVNM+Hm2GVuCcAAAAAAAAAAAq6aHAHZ2sd9aPbRsskrlXMLWIwqs4Sv2Bk+VwuIR+9wAAABdIdugAAAAAAAAAAAIu2qsYAAAAQERzKOqYYiPXNwsiL8ADAG/f45RBssmf3umGzw4qKkLGlObuPdX0buWmTGrhI13SG38F2V8Mp9DI+eDkcCjMSAOGVuCcAAAAQHnm0o/r+Gsl+6oqBgSbqoSY37gflvQB3zZRghuir0N75UVerd0Q50yG5Zfu08i2crhx6uk+5HYTl8/Sa7uZ+Qc=\",\n"
+ + " \"resultXdr\": \"AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAA=\",\n"
+ + " \"resultMetaXdr\": \"AAAAAwAAAAAAAAACAAAAAwAc0RsAAAAAAAAAALgRm6n57AKz92hLeEpt4BrgS+IEeoAVgzT2ge4u2qsYAAAAADwzS2gAGgQZAAAANQAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAABzPVAAAAABmWdZ2AAAAAAAAAAEAHNEbAAAAAAAAAAC4EZup+ewCs/doS3hKbeAa4EviBHqAFYM09oHuLtqrGAAAAAA8M0toABoEGQAAADYAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAc0RsAAAAAZlnf2gAAAAAAAAABAAAAAwAAAAMAHNEaAAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnABZJUSd0V2hAAAAawAAAlEAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAaBGEAAAAAZkspCwAAAAAAAAABABzRGwAAAAAAAAAAEH3Rayw4M0iCLoEe96rPFNGYim8AVHJU0z4ebYZW4JwAWSUtVVp1oQAAAGsAAAJRAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAGgRhAAAAAGZLKQsAAAAAAAAAAAAc0RsAAAAAAAAAACrpocAdnax31o9tGyySuVcwtYjCqzhK/YGT5XC4hH73AAAAF0h26AAAHNEbAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n"
+ + " \"ledger\": 1888539,\n"
+ + " \"createdAt\": 1717166042\n"
+ + " },\n"
+ + " {\n"
+ + " \"status\": \"SUCCESS\",\n"
+ + " \"applicationOrder\": 3,\n"
+ + " \"feeBump\": false,\n"
+ + " \"envelopeXdr\": \"AAAAAgAAAACwtG/IRC5DZE1UdekijEsoQEPM/uOwZ3iY/Y8UZ3b9xAAPQkAAGgRHAAAANgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAABB90WssODNIgi6BHveqzxTRmIpvAFRyVNM+Hm2GVuCcAAAAAAAAAADgdupKeB04lazKXCOb+E1JfxaM3tI4Xsb/qDa1MWOvXgAAABdIdugAAAAAAAAAAAJndv3EAAAAQKcTimw6KKcM0AeCMxXJcEK/hS9ROoj/qpMFppGNAr4W3ifSOSTGAFbA+cIVHmaV4p7xGcR+9JnUN1YjamvJZwSGVuCcAAAAQK9Cp775JbnYA793SXkkWWbmvnEFTiDPiFyTHxTphCwBDB1zqkXqGG6Q5O3dAyqkNJvj1XNRDsmY4pKV41qijQU=\",\n"
+ + " \"resultXdr\": \"AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAA=\",\n"
+ + " \"resultMetaXdr\": \"AAAAAwAAAAAAAAACAAAAAwAc0RsAAAAAAAAAALC0b8hELkNkTVR16SKMSyhAQ8z+47BneJj9jxRndv3EAAAAADwzS2gAGgRHAAAANQAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAABzPVAAAAABmWdZ2AAAAAAAAAAEAHNEbAAAAAAAAAACwtG/IRC5DZE1UdekijEsoQEPM/uOwZ3iY/Y8UZ3b9xAAAAAA8M0toABoERwAAADYAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAc0RsAAAAAZlnf2gAAAAAAAAABAAAAAwAAAAMAHNEbAAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnABZJS1VWnWhAAAAawAAAlEAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAaBGEAAAAAZkspCwAAAAAAAAABABzRGwAAAAAAAAAAEH3Rayw4M0iCLoEe96rPFNGYim8AVHJU0z4ebYZW4JwAWSUWDOONoQAAAGsAAAJRAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAGgRhAAAAAGZLKQsAAAAAAAAAAAAc0RsAAAAAAAAAAOB26kp4HTiVrMpcI5v4TUl/Foze0jhexv+oNrUxY69eAAAAF0h26AAAHNEbAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\n"
+ + " \"ledger\": 1888539,\n"
+ + " \"createdAt\": 1717166042\n"
+ + " },\n"
+ + " {\n"
+ + " \"status\": \"SUCCESS\",\n"
+ + " \"applicationOrder\": 4,\n"
+ + " \"feeBump\": false,\n"
+ + " \"envelopeXdr\": \"AAAAAgAAAACxMt2gKYOehEoVbmh9vfvZ4mVzXFSNTbAU5S4a8zorrAA4wrwAHLqRAAAADAAAAAAAAAAAAAAAAQAAAAAAAAAYAAAAAQAAAAAAAAAAAAAAALEy3aApg56EShVuaH29+9niZXNcVI1NsBTlLhrzOiusz3K+BVgRzXig/Bhz1TL5Qy+Ibv6cDvCfdaAtBMMFPcYAAAAAHXUVmJM11pdJSKKV52UJrVYlvxaPLmmg17nMe0HGy0MAAAABAAAAAAAAAAEAAAAAAAAAAAAAAACxMt2gKYOehEoVbmh9vfvZ4mVzXFSNTbAU5S4a8zorrM9yvgVYEc14oPwYc9Uy+UMviG7+nA7wn3WgLQTDBT3GAAAAAB11FZiTNdaXSUiiledlCa1WJb8Wjy5poNe5zHtBxstDAAAAAAAAAAEAAAAAAAAAAQAAAAcddRWYkzXWl0lIopXnZQmtViW/Fo8uaaDXucx7QcbLQwAAAAEAAAAGAAAAAbolCtTsMrJvK0M2SaskFsaMajj3iAZbXxELZHwDyE5dAAAAFAAAAAEABf2jAAAd1AAAAGgAAAAAADjCWAAAAAHzOiusAAAAQM+qaiMKxMoCVNjdRIh3X9CSxkjAm0BpXYDB9Fd+DS0guYKiY3TMaVe243UB008iBn5ynQv724rReXlg7iFqXQA=\",\n"
+ + " \"resultXdr\": \"AAAAAAAw3cUAAAAAAAAAAQAAAAAAAAAYAAAAAKg/pGuhtOG27rIpG8xhUIp46CStGWOcsGlNsTQv44UOAAAAAA==\",\n"
+ + " \"resultMetaXdr\": \"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\",\n"
+ + " \"diagnosticEventsXdr\": [\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACnJlYWRfZW50cnkAAAAAAAUAAAAAAAAAAg==\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAC3dyaXRlX2VudHJ5AAAAAAUAAAAAAAAAAQ==\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEGxlZGdlcl9yZWFkX2J5dGUAAAAFAAAAAAAAHdQ=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEWxlZGdlcl93cml0ZV9ieXRlAAAAAAAABQAAAAAAAABo\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADXJlYWRfa2V5X2J5dGUAAAAAAAAFAAAAAAAAAFQ=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADndyaXRlX2tleV9ieXRlAAAAAAAFAAAAAAAAAAA=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADnJlYWRfZGF0YV9ieXRlAAAAAAAFAAAAAAAAAAA=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD3dyaXRlX2RhdGFfYnl0ZQAAAAAFAAAAAAAAAGg=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAADnJlYWRfY29kZV9ieXRlAAAAAAAFAAAAAAAAHdQ=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD3dyaXRlX2NvZGVfYnl0ZQAAAAAFAAAAAAAAAAA=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACmVtaXRfZXZlbnQAAAAAAAUAAAAAAAAAAA==\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD2VtaXRfZXZlbnRfYnl0ZQAAAAAFAAAAAAAAAAA=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACGNwdV9pbnNuAAAABQAAAAAABTO4\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAACG1lbV9ieXRlAAAABQAAAAAAAPkD\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEWludm9rZV90aW1lX25zZWNzAAAAAAAABQAAAAAAAmiz\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAD21heF9yd19rZXlfYnl0ZQAAAAAFAAAAAAAAADA=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEG1heF9yd19kYXRhX2J5dGUAAAAFAAAAAAAAAGg=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAEG1heF9yd19jb2RlX2J5dGUAAAAFAAAAAAAAHdQ=\",\n"
+ + " \"AAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAAADwAAAAxjb3JlX21ldHJpY3MAAAAPAAAAE21heF9lbWl0X2V2ZW50X2J5dGUAAAAABQAAAAAAAAAA\"\n"
+ + " ],\n"
+ + " \"ledger\": 1888539,\n"
+ + " \"createdAt\": 1717166042\n"
+ + " },\n"
+ + " {\n"
+ + " \"status\": \"FAILED\",\n"
+ + " \"applicationOrder\": 1,\n"
+ + " \"feeBump\": false,\n"
+ + " \"envelopeXdr\": \"AAAAAgAAAAAxLMEcxmfUgNzL687Js4sX/jmFQDqTo1Lj4KDoC1PeSQAehIAAAAIJAAtMUQAAAAEAAAAAAAAAAAAAAABmWeAVAAAAAQAAAAlwc3BiOjMyMTcAAAAAAAACAAAAAQAAAACKlutUN5GT3UOoE2BUkNtJEwoipGOinBFsQtXgpIZMxQAAAAEAAAAA433o+yremWU3t88cKpfpHR+JMFR44JHzmBGni6hqCEYAAAACQVRVQUgAAAAAAAAAAAAAAGfK1mN4mg51jbX6by6TWghGynQ463doEDgzriqZo9bzAAAAAAaOd4AAAAABAAAAAIqW61Q3kZPdQ6gTYFSQ20kTCiKkY6KcEWxC1eCkhkzFAAAAAQAAAADjfej7Kt6ZZTe3zxwql+kdH4kwVHjgkfOYEaeLqGoIRgAAAAJBVFVTRAAAAAAAAAAAAAAAZ8rWY3iaDnWNtfpvLpNaCEbKdDjrd2gQODOuKpmj1vMAAAAAADh1IAAAAAAAAAACC1PeSQAAAEBoad/kqj/4Sqq5tC6HyeMm5LJKM1VqKRGZc3e4uvA3ITThwn2nNMRJRegdQrLrPBTSgw51nY8npilXVIds7I0OpIZMxQAAAEDTZNaLjIDMWPDdCxa1ZB28vUxTcS/0xykOFTI/JAz096vX6Y7wI0QvnbPM7KCoL0cJAciD+pJxNqXQ2Aff1hoO\",\n"
+ + " \"resultXdr\": \"AAAAAAAAAMj/////AAAAAgAAAAAAAAAB////+wAAAAAAAAAB////+wAAAAA=\",\n"
+ + " \"resultMetaXdr\": \"AAAAAwAAAAAAAAACAAAAAwAc0RwAAAAAAAAAADEswRzGZ9SA3Mvrzsmzixf+OYVAOpOjUuPgoOgLU95JAAAAFxzxIbUAAAIJAAtMUAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAABzRGgAAAABmWd/VAAAAAAAAAAEAHNEcAAAAAAAAAAAxLMEcxmfUgNzL687Js4sX/jmFQDqTo1Lj4KDoC1PeSQAAABcc8SG1AAACCQALTFEAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAADAAAAAAAc0RwAAAAAZlnf3wAAAAAAAAAAAAAAAAAAAAA=\",\n"
+ + " \"ledger\": 1888540,\n"
+ + " \"createdAt\": 1717166047\n"
+ + " }\n"
+ + " ],\n"
+ + " \"latestLedger\": 1888542,\n"
+ + " \"latestLedgerCloseTimestamp\": 1717166057,\n"
+ + " \"oldestLedger\": 1871263,\n"
+ + " \"oldestLedgerCloseTimestamp\": 1717075350,\n"
+ + " \"cursor\": \"8111217537191937\"\n"
+ + " }\n"
+ + "}";
+
+ GetTransactionsRequest.PaginationOptions paginationOptions =
+ GetTransactionsRequest.PaginationOptions.builder().limit(5L).build();
+ GetTransactionsRequest getTransactionsRequest =
+ GetTransactionsRequest.builder()
+ .startLedger(1888539L)
+ .pagination(paginationOptions)
+ .build();
+
+ MockWebServer mockWebServer = new MockWebServer();
+ Dispatcher dispatcher =
+ new Dispatcher() {
+ @NotNull
+ @Override
+ public MockResponse dispatch(@NotNull RecordedRequest recordedRequest)
+ throws InterruptedException {
+ SorobanRpcRequest sorobanRpcRequest =
+ gson.fromJson(
+ recordedRequest.getBody().readUtf8(),
+ new TypeToken>() {}.getType());
+ if ("POST".equals(recordedRequest.getMethod())
+ && sorobanRpcRequest.getMethod().equals("getTransactions")
+ && sorobanRpcRequest.getParams().equals(getTransactionsRequest)) {
+ return new MockResponse().setResponseCode(200).setBody(json);
+ }
+ return new MockResponse().setResponseCode(404);
+ }
+ };
+ mockWebServer.setDispatcher(dispatcher);
+ mockWebServer.start();
+
+ HttpUrl baseUrl = mockWebServer.url("");
+ SorobanServer server = new SorobanServer(baseUrl.toString());
+ GetTransactionsResponse resp = server.getTransactions(getTransactionsRequest);
+ assertEquals(resp.getLatestLedger().longValue(), 1888542L);
+ assertEquals(resp.getLatestLedgerCloseTimestamp().longValue(), 1717166057L);
+ assertEquals(resp.getOldestLedger().longValue(), 1871263L);
+ assertEquals(resp.getOldestLedgerCloseTimestamp().longValue(), 1717075350L);
+ assertEquals(resp.getCursor(), "8111217537191937");
+ assertEquals(resp.getTransactions().size(), 5);
+ assertEquals(
+ resp.getTransactions().get(0).getStatus(),
+ GetTransactionsResponse.TransactionStatus.FAILED);
+ assertEquals(resp.getTransactions().get(0).getApplicationOrder().longValue(), 1L);
+ assertEquals(resp.getTransactions().get(0).getFeeBump(), false);
+ assertEquals(
+ resp.getTransactions().get(0).getEnvelopeXdr(),
+ resp.getTransactions().get(0).parseEnvelopeXdr().toXdrBase64());
+ assertEquals(
+ resp.getTransactions().get(0).getResultXdr(),
+ resp.getTransactions().get(0).parseResultXdr().toXdrBase64());
+ assertEquals(
+ resp.getTransactions().get(0).getResultMetaXdr(),
+ resp.getTransactions().get(0).parseResultMetaXdr().toXdrBase64());
+ assertEquals(resp.getTransactions().get(0).getLedger().longValue(), 1888539L);
+ assertEquals(resp.getTransactions().get(1).getCreatedAt().longValue(), 1717166042L);
+
+ assertEquals(
+ resp.getTransactions().get(3).getStatus(),
+ GetTransactionsResponse.TransactionStatus.SUCCESS);
+ assertEquals(resp.getTransactions().get(3).getApplicationOrder().longValue(), 4L);
+ assertEquals(resp.getTransactions().get(3).getFeeBump(), false);
+ assertEquals(
+ resp.getTransactions().get(3).getEnvelopeXdr(),
+ resp.getTransactions().get(3).parseEnvelopeXdr().toXdrBase64());
+ assertEquals(
+ resp.getTransactions().get(3).getResultXdr(),
+ resp.getTransactions().get(3).parseResultXdr().toXdrBase64());
+ assertEquals(
+ resp.getTransactions().get(3).getResultMetaXdr(),
+ resp.getTransactions().get(3).parseResultMetaXdr().toXdrBase64());
+ assertEquals(resp.getTransactions().get(3).getLedger().longValue(), 1888539L);
+ assertEquals(resp.getTransactions().get(3).getDiagnosticEventsXdr().size(), 19);
+ for (int i = 0; i < 19; i++) {
+ assertEquals(
+ resp.getTransactions().get(3).getDiagnosticEventsXdr().get(i),
+ resp.getTransactions().get(3).parseDiagnosticEventsXdr().get(i).toXdrBase64());
+ }
+ assertEquals(resp.getTransactions().get(0).getLedger().longValue(), 1888539L);
+ assertEquals(resp.getTransactions().get(1).getCreatedAt().longValue(), 1717166042L);
+
+ server.close();
+ mockWebServer.close();
+ }
+
@Test
public void testGetEvents() throws IOException, SorobanRpcException {
String json =