voteSlots();
+ /**
+ * A hint indicating which page of the sender's owner directory links to this object, in case the directory consists
+ * of multiple pages.
+ *
+ * Note: The object does not contain a direct link to the owner directory containing it, since that value can be
+ * derived from the Account.
+ *
+ * @return A {@link String} containing the owner node hint.
+ */
+ @JsonProperty("OwnerNode")
+ String ownerNode();
+
/**
* Unwraps the {@link VoteEntryWrapper}s in {@link #voteSlots()} for easier access to {@link VoteEntry}s.
*
@@ -129,4 +142,11 @@ default List voteSlotsUnwrapped() {
.map(VoteEntryWrapper::voteEntry)
.collect(Collectors.toList());
}
+
+ /**
+ * The unique ID of the {@link AmmObject}.
+ *
+ * @return A {@link Hash256}.
+ */
+ Hash256 index();
}
diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/TicketObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/TicketObject.java
index 0a3a834fe..f103989d7 100644
--- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/TicketObject.java
+++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/TicketObject.java
@@ -110,4 +110,11 @@ default Flags flags() {
*/
@JsonProperty("TicketSequence")
UnsignedInteger ticketSequence();
+
+ /**
+ * The unique ID of the {@link TicketObject}.
+ *
+ * @return A {@link Hash256}.
+ */
+ Hash256 index();
}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/TestConstants.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/TestConstants.java
index 1de8d07cb..534fb6d5f 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/TestConstants.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/crypto/TestConstants.java
@@ -26,6 +26,7 @@
import org.xrpl.xrpl4j.crypto.keys.PrivateKey;
import org.xrpl.xrpl4j.crypto.keys.PublicKey;
import org.xrpl.xrpl4j.model.transactions.Address;
+import org.xrpl.xrpl4j.model.transactions.Hash256;
/**
* Constants used for testing.
@@ -74,4 +75,9 @@ static PrivateKey getEcPrivateKey() {
// Both generated from Passphrase.of("hello")
Address ED_ADDRESS = Address.of("rwGWYtRR6jJJJq7FKQg74YwtkiPyUqJ466");
Address EC_ADDRESS = Address.of("rD8ATvjj9mfnFuYYTGRNb9DygnJW9JNN1C");
+
+ /**
+ * A sample {@link Hash256}.
+ */
+ Hash256 HASH_256 = Hash256.of("6B1011EF3BC3ED619B15979EF75C1C60D9181F3DDE641AD3019318D3900CEE2E");
}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParamsTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParamsTest.java
new file mode 100644
index 000000000..1955540d3
--- /dev/null
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParamsTest.java
@@ -0,0 +1,432 @@
+package org.xrpl.xrpl4j.model.client.ledger;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.xrpl.xrpl4j.crypto.TestConstants.ED_ADDRESS;
+import static org.xrpl.xrpl4j.crypto.TestConstants.HASH_256;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.primitives.UnsignedInteger;
+import org.json.JSONException;
+import org.junit.jupiter.api.Test;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
+import org.xrpl.xrpl4j.model.AbstractJsonTest;
+import org.xrpl.xrpl4j.model.client.XrplRequestParams;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
+import org.xrpl.xrpl4j.model.client.ledger.RippleStateLedgerEntryParams.RippleStateAccounts;
+import org.xrpl.xrpl4j.model.ledger.AccountRootObject;
+import org.xrpl.xrpl4j.model.ledger.AmmObject;
+import org.xrpl.xrpl4j.model.ledger.CheckObject;
+import org.xrpl.xrpl4j.model.ledger.DepositPreAuthObject;
+import org.xrpl.xrpl4j.model.ledger.EscrowObject;
+import org.xrpl.xrpl4j.model.ledger.Issue;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
+import org.xrpl.xrpl4j.model.ledger.NfTokenPageObject;
+import org.xrpl.xrpl4j.model.ledger.OfferObject;
+import org.xrpl.xrpl4j.model.ledger.PayChannelObject;
+import org.xrpl.xrpl4j.model.ledger.RippleStateObject;
+import org.xrpl.xrpl4j.model.ledger.TicketObject;
+import org.xrpl.xrpl4j.model.transactions.Address;
+
+class LedgerEntryRequestParamsTest extends AbstractJsonTest {
+
+ @Test
+ void testTypedIndexParams() throws JSONException, JsonProcessingException {
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.index(HASH_256, AmmObject.class,
+ LedgerSpecifier.VALIDATED);
+ assertThat(params.index()).isNotEmpty().get().isEqualTo(HASH_256);
+ assertThat(params.ledgerObjectClass()).isEqualTo(AmmObject.class);
+
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = String.format("{\n" +
+ " \"index\": \"%s\",\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }", HASH_256);
+
+ String serialized = objectMapper.writeValueAsString(params);
+ JSONAssert.assertEquals(json, serialized, JSONCompareMode.STRICT);
+
+ // Note that when deserializing from JSON, we cannot figure out what ledgerObjectClass should be based on the JSON.
+ // This is likely fine because request params should never really be getting deserialized by this library.
+ XrplRequestParams deserialized = objectMapper.readValue(serialized, params.getClass());
+ assertThat(deserialized).usingRecursiveComparison().ignoringFields("ledgerObjectClass")
+ .isEqualTo(params);
+ }
+
+ @Test
+ void testUntypedIndexParams() throws JSONException, JsonProcessingException {
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.index(HASH_256, LedgerSpecifier.VALIDATED);
+ assertThat(params.index()).isNotEmpty().get().isEqualTo(HASH_256);
+ assertThat(params.ledgerObjectClass()).isEqualTo(LedgerObject.class);
+
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = String.format("{\n" +
+ " \"index\": \"%s\",\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }", HASH_256);
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testAccountRootParams() throws JSONException, JsonProcessingException {
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.accountRoot(
+ ED_ADDRESS, LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.accountRoot()).isNotEmpty().get().isEqualTo(ED_ADDRESS);
+ assertThat(params.ledgerObjectClass()).isEqualTo(AccountRootObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = String.format("{\n" +
+ " \"account_root\": \"%s\",\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }", ED_ADDRESS);
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testAmmParams() throws JSONException, JsonProcessingException {
+ AmmLedgerEntryParams ammParams = AmmLedgerEntryParams.builder()
+ .asset(Issue.XRP)
+ .asset2(
+ Issue.builder()
+ .currency("TST")
+ .issuer(Address.of("rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd"))
+ .build()
+ )
+ .build();
+
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.amm(ammParams, LedgerSpecifier.VALIDATED);
+ assertThat(params.amm()).isNotEmpty().get().isEqualTo(ammParams);
+ assertThat(params.ledgerObjectClass()).isEqualTo(AmmObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = "{\n" +
+ " \"amm\": {\n" +
+ " \"asset\": {\n" +
+ " \"currency\": \"XRP\"\n" +
+ " },\n" +
+ " \"asset2\": {\n" +
+ " \"currency\" : \"TST\",\n" +
+ " \"issuer\" : \"rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testOfferParams() throws JSONException, JsonProcessingException {
+ OfferLedgerEntryParams offerParams = OfferLedgerEntryParams.builder()
+ .account(Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"))
+ .seq(UnsignedInteger.valueOf(359))
+ .build();
+
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.offer(
+ offerParams, LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.offer()).isNotEmpty().get().isEqualTo(offerParams);
+ assertThat(params.ledgerObjectClass()).isEqualTo(OfferObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = "{\n" +
+ " \"offer\": {\n" +
+ " \"account\": \"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" +
+ " \"seq\": 359\n" +
+ " },\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testRippleStateParams() throws JSONException, JsonProcessingException {
+ RippleStateLedgerEntryParams rippleStateParams = RippleStateLedgerEntryParams.builder()
+ .accounts(RippleStateAccounts.of(
+ Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"),
+ Address.of("rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW")
+ ))
+ .currency("USD")
+ .build();
+
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.rippleState(
+ rippleStateParams, LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.rippleState()).isNotEmpty().get().isEqualTo(rippleStateParams);
+ assertThat(params.ledgerObjectClass()).isEqualTo(RippleStateObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = "{\n" +
+ " \"ripple_state\": {\n" +
+ " \"accounts\": [\n" +
+ " \"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" +
+ " \"rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW\"\n" +
+ " ],\n" +
+ " \"currency\": \"USD\"\n" +
+ " },\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testCheckParams() throws JSONException, JsonProcessingException {
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.check(HASH_256, LedgerSpecifier.VALIDATED);
+ assertThat(params.check()).isNotEmpty().get().isEqualTo(HASH_256);
+ assertThat(params.ledgerObjectClass()).isEqualTo(CheckObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = String.format("{\n" +
+ " \"check\": \"%s\",\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }", HASH_256);
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testEscrowParams() throws JSONException, JsonProcessingException {
+ EscrowLedgerEntryParams escrowParams = EscrowLedgerEntryParams.builder()
+ .owner(Address.of("rL4fPHi2FWGwRGRQSH7gBcxkuo2b9NTjKK"))
+ .seq(UnsignedInteger.valueOf(126))
+ .build();
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.escrow(
+ escrowParams, LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.escrow()).isNotEmpty().get().isEqualTo(escrowParams);
+ assertThat(params.ledgerObjectClass()).isEqualTo(EscrowObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = "{\n" +
+ " \"escrow\": {\n" +
+ " \"owner\": \"rL4fPHi2FWGwRGRQSH7gBcxkuo2b9NTjKK\",\n" +
+ " \"seq\": 126\n" +
+ " },\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testPaymentChannelParams() throws JSONException, JsonProcessingException {
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.paymentChannel(
+ HASH_256, LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.paymentChannel()).isNotEmpty().get().isEqualTo(HASH_256);
+ assertThat(params.ledgerObjectClass()).isEqualTo(PayChannelObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = String.format("{\n" +
+ " \"payment_channel\": \"%s\",\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }", HASH_256);
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testDepositPreAuthParams() throws JSONException, JsonProcessingException {
+ DepositPreAuthLedgerEntryParams depositPreAuthParams = DepositPreAuthLedgerEntryParams.builder()
+ .owner(Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"))
+ .authorized(Address.of("ra5nK24KXen9AHvsdFTKHSANinZseWnPcX"))
+ .build();
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.depositPreAuth(
+ depositPreAuthParams,
+ LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.depositPreAuth()).isNotEmpty().get().isEqualTo(depositPreAuthParams);
+ assertThat(params.ledgerObjectClass()).isEqualTo(DepositPreAuthObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = "{\n" +
+ " \"deposit_preauth\": {\n" +
+ " \"owner\": \"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" +
+ " \"authorized\": \"ra5nK24KXen9AHvsdFTKHSANinZseWnPcX\"\n" +
+ " },\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testTicketParams() throws JSONException, JsonProcessingException {
+ TicketLedgerEntryParams ticketParams = TicketLedgerEntryParams.builder()
+ .account(Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"))
+ .ticketSeq(UnsignedInteger.valueOf(389))
+ .build();
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.ticket(
+ ticketParams,
+ LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.ticket()).isNotEmpty().get().isEqualTo(ticketParams);
+ assertThat(params.ledgerObjectClass()).isEqualTo(TicketObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.nftPage()).isEmpty();
+
+ String json = "{\n" +
+ " \"ticket\": {\n" +
+ " \"account\": \"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" +
+ " \"ticket_seq\": 389\n" +
+ " },\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+
+ @Test
+ void testNftPageParams() throws JSONException, JsonProcessingException {
+ LedgerEntryRequestParams params = LedgerEntryRequestParams.nftPage(
+ HASH_256,
+ LedgerSpecifier.VALIDATED
+ );
+ assertThat(params.nftPage()).isNotEmpty().get().isEqualTo(HASH_256);
+ assertThat(params.ledgerObjectClass()).isEqualTo(NfTokenPageObject.class);
+
+ assertThat(params.index()).isEmpty();
+ assertThat(params.accountRoot()).isEmpty();
+ assertThat(params.amm()).isEmpty();
+ assertThat(params.offer()).isEmpty();
+ assertThat(params.rippleState()).isEmpty();
+ assertThat(params.check()).isEmpty();
+ assertThat(params.escrow()).isEmpty();
+ assertThat(params.paymentChannel()).isEmpty();
+ assertThat(params.depositPreAuth()).isEmpty();
+ assertThat(params.ticket()).isEmpty();
+
+ String json = String.format("{\n" +
+ " \"nft_page\": \"%s\",\n" +
+ " \"binary\": false,\n" +
+ " \"ledger_index\": \"validated\"\n" +
+ " }", HASH_256);
+
+ assertCanSerializeAndDeserialize(params, json);
+ }
+}
\ No newline at end of file
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryResultTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryResultTest.java
new file mode 100644
index 000000000..8bcfb0a8d
--- /dev/null
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryResultTest.java
@@ -0,0 +1,676 @@
+package org.xrpl.xrpl4j.model.client.ledger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.xrpl.xrpl4j.crypto.TestConstants.HASH_256;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.primitives.UnsignedInteger;
+import com.google.common.primitives.UnsignedLong;
+import org.json.JSONException;
+import org.junit.jupiter.api.Test;
+import org.xrpl.xrpl4j.model.AbstractJsonTest;
+import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
+import org.xrpl.xrpl4j.model.flags.AccountRootFlags;
+import org.xrpl.xrpl4j.model.flags.OfferFlags;
+import org.xrpl.xrpl4j.model.flags.RippleStateFlags;
+import org.xrpl.xrpl4j.model.ledger.AccountRootObject;
+import org.xrpl.xrpl4j.model.ledger.AmmObject;
+import org.xrpl.xrpl4j.model.ledger.AuctionSlot;
+import org.xrpl.xrpl4j.model.ledger.CheckObject;
+import org.xrpl.xrpl4j.model.ledger.DepositPreAuthObject;
+import org.xrpl.xrpl4j.model.ledger.EscrowObject;
+import org.xrpl.xrpl4j.model.ledger.Issue;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
+import org.xrpl.xrpl4j.model.ledger.NfToken;
+import org.xrpl.xrpl4j.model.ledger.NfTokenPageObject;
+import org.xrpl.xrpl4j.model.ledger.NfTokenWrapper;
+import org.xrpl.xrpl4j.model.ledger.OfferObject;
+import org.xrpl.xrpl4j.model.ledger.PayChannelObject;
+import org.xrpl.xrpl4j.model.ledger.RippleStateObject;
+import org.xrpl.xrpl4j.model.ledger.TicketObject;
+import org.xrpl.xrpl4j.model.ledger.VoteEntry;
+import org.xrpl.xrpl4j.model.ledger.VoteEntryWrapper;
+import org.xrpl.xrpl4j.model.transactions.Address;
+import org.xrpl.xrpl4j.model.transactions.Hash256;
+import org.xrpl.xrpl4j.model.transactions.IssuedCurrencyAmount;
+import org.xrpl.xrpl4j.model.transactions.NfTokenId;
+import org.xrpl.xrpl4j.model.transactions.NfTokenUri;
+import org.xrpl.xrpl4j.model.transactions.TradingFee;
+import org.xrpl.xrpl4j.model.transactions.VoteWeight;
+import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
+
+class LedgerEntryResultTest extends AbstractJsonTest {
+
+ @Test
+ void testAccountRootResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83125250)))
+ .ledgerHash(Hash256.of("783625588CF01BD3D0E9C2719B92098A6A87649AEFF5AE970CD68B911436C1D7"))
+ .validated(true)
+ .index(Hash256.of("13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8"))
+ .node(
+ AccountRootObject.builder()
+ .account(Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"))
+ .accountTransactionId(Hash256.of("932CC7E9BAC1F7B9FA5381679F293EEC0A646E5E7F2F6D14C85FEE2102F0E66C"))
+ .balance(XrpCurrencyAmount.ofDrops(1066107694))
+ .domain("6D64756F31332E636F6D")
+ .emailHash("98B4375E1D753E5B91627516F6D70977")
+ .flags(AccountRootFlags.of(9568256))
+ .messageKey("0000000000000000000000070000000300")
+ .ownerCount(UnsignedInteger.valueOf(17))
+ .previousTransactionId(Hash256.of("7E5F3FB60E1177F8AF8A9EAC7982F27FA5494FDEA871B23B4B149939A5A7A7BB"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(82357607))
+ .regularKey(Address.of("rD9iJmieYHn8jTtPjwwkW2Wm9sVDvPXLoJ"))
+ .sequence(UnsignedInteger.valueOf(393))
+ .ticketCount(UnsignedInteger.valueOf(5))
+ .transferRate(UnsignedInteger.valueOf(4294967295L))
+ .index(Hash256.of("13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"783625588CF01BD3D0E9C2719B92098A6A87649AEFF5AE970CD68B911436C1D7\",\n" +
+ " \"ledger_index\": 83125250,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8\",\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" +
+ " \"AccountTxnID\": \"932CC7E9BAC1F7B9FA5381679F293EEC0A646E5E7F2F6D14C85FEE2102F0E66C\",\n" +
+ " \"Balance\": \"1066107694\",\n" +
+ " \"Domain\": \"6D64756F31332E636F6D\",\n" +
+ " \"EmailHash\": \"98B4375E1D753E5B91627516F6D70977\",\n" +
+ " \"Flags\": 9568256,\n" +
+ " \"LedgerEntryType\": \"AccountRoot\",\n" +
+ " \"MessageKey\": \"0000000000000000000000070000000300\",\n" +
+ " \"OwnerCount\": 17,\n" +
+ " \"PreviousTxnID\": \"7E5F3FB60E1177F8AF8A9EAC7982F27FA5494FDEA871B23B4B149939A5A7A7BB\",\n" +
+ " \"PreviousTxnLgrSeq\": 82357607,\n" +
+ " \"RegularKey\": \"rD9iJmieYHn8jTtPjwwkW2Wm9sVDvPXLoJ\",\n" +
+ " \"Sequence\": 393,\n" +
+ " \"TicketCount\": 5,\n" +
+ " \"TransferRate\": 4294967295,\n" +
+ " \"index\": \"13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testAmmResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(607272)))
+ .ledgerHash(Hash256.of("EEB650A0FD3CF0A5CE68B3DBD67C902FEC85E6AFAE1D0A7A7AF4BAD2F38557C7"))
+ .validated(true)
+ .index(Hash256.of("6BCD7E451DDA015FB307DAD9208A98A2DC3AC4D1448E624B42C89246DCF08692"))
+ .node(
+ AmmObject.builder()
+ .account(Address.of("rNqXnvSYbjZeJQ6jWcf6T5mnNMRPzHXaZW"))
+ .asset(Issue.XRP)
+ .asset2(
+ Issue.builder()
+ .currency("7872706C346A436F696E00000000000000000000")
+ .issuer(Address.of("rDeo7rDoYw6AUKGneWwfkHPsMJagxcGWy1"))
+ .build()
+ )
+ .auctionSlot(
+ AuctionSlot.builder()
+ .account(Address.of("rDeo7rDoYw6AUKGneWwfkHPsMJagxcGWy1"))
+ .discountedFee(TradingFee.of(UnsignedInteger.valueOf(77)))
+ .expiration(UnsignedInteger.valueOf(750359162))
+ .price(
+ IssuedCurrencyAmount.builder()
+ .currency("03DCF8F3910BFE6AB56136A90BD41E0902E23C4F")
+ .value("0")
+ .issuer(Address.of("rNqXnvSYbjZeJQ6jWcf6T5mnNMRPzHXaZW"))
+ .build()
+ )
+ .build()
+ )
+ .lpTokenBalance(
+ IssuedCurrencyAmount.builder()
+ .currency("03DCF8F3910BFE6AB56136A90BD41E0902E23C4F")
+ .issuer(Address.of("rNqXnvSYbjZeJQ6jWcf6T5mnNMRPzHXaZW"))
+ .value("70606.68056410846")
+ .build()
+ )
+ .ownerNode("0")
+ .tradingFee(TradingFee.of(UnsignedInteger.valueOf(778)))
+ .addVoteSlots(
+ VoteEntryWrapper.of(VoteEntry.builder()
+ .account(Address.of("rDeo7rDoYw6AUKGneWwfkHPsMJagxcGWy1"))
+ .tradingFee(TradingFee.of(UnsignedInteger.valueOf(1000)))
+ .voteWeight(VoteWeight.of(UnsignedInteger.valueOf(70815)))
+ .build()),
+ VoteEntryWrapper.of(VoteEntry.builder()
+ .account(Address.of("rHPoJo9R3QdQjK6XdWL5hY2eTc4wUeNYzW"))
+ .tradingFee(TradingFee.of(UnsignedInteger.valueOf(240)))
+ .voteWeight(VoteWeight.of(UnsignedInteger.valueOf(29185)))
+ .build())
+ )
+ .index(Hash256.of("6BCD7E451DDA015FB307DAD9208A98A2DC3AC4D1448E624B42C89246DCF08692"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"index\": \"6BCD7E451DDA015FB307DAD9208A98A2DC3AC4D1448E624B42C89246DCF08692\",\n" +
+ " \"ledger_hash\": \"EEB650A0FD3CF0A5CE68B3DBD67C902FEC85E6AFAE1D0A7A7AF4BAD2F38557C7\",\n" +
+ " \"ledger_index\": 607272,\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rNqXnvSYbjZeJQ6jWcf6T5mnNMRPzHXaZW\",\n" +
+ " \"Asset\": {\n" +
+ " \"currency\": \"XRP\"\n" +
+ " },\n" +
+ " \"Asset2\": {\n" +
+ " \"currency\": \"7872706C346A436F696E00000000000000000000\",\n" +
+ " \"issuer\": \"rDeo7rDoYw6AUKGneWwfkHPsMJagxcGWy1\"\n" +
+ " },\n" +
+ " \"AuctionSlot\": {\n" +
+ " \"Account\": \"rDeo7rDoYw6AUKGneWwfkHPsMJagxcGWy1\",\n" +
+ " \"DiscountedFee\": 77,\n" +
+ " \"Expiration\": 750359162,\n" +
+ " \"Price\": {\n" +
+ " \"currency\": \"03DCF8F3910BFE6AB56136A90BD41E0902E23C4F\",\n" +
+ " \"issuer\": \"rNqXnvSYbjZeJQ6jWcf6T5mnNMRPzHXaZW\",\n" +
+ " \"value\": \"0\"\n" +
+ " }\n" +
+ " },\n" +
+ " \"Flags\": 0,\n" +
+ " \"LPTokenBalance\": {\n" +
+ " \"currency\": \"03DCF8F3910BFE6AB56136A90BD41E0902E23C4F\",\n" +
+ " \"issuer\": \"rNqXnvSYbjZeJQ6jWcf6T5mnNMRPzHXaZW\",\n" +
+ " \"value\": \"70606.68056410846\"\n" +
+ " },\n" +
+ " \"LedgerEntryType\": \"AMM\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"TradingFee\": 778,\n" +
+ " \"VoteSlots\": [\n" +
+ " {\n" +
+ " \"VoteEntry\": {\n" +
+ " \"Account\": \"rDeo7rDoYw6AUKGneWwfkHPsMJagxcGWy1\",\n" +
+ " \"TradingFee\": 1000,\n" +
+ " \"VoteWeight\": 70815\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"VoteEntry\": {\n" +
+ " \"Account\": \"rHPoJo9R3QdQjK6XdWL5hY2eTc4wUeNYzW\",\n" +
+ " \"TradingFee\": 240,\n" +
+ " \"VoteWeight\": 29185\n" +
+ " }\n" +
+ " }\n" +
+ " ],\n" +
+ " \"index\": \"6BCD7E451DDA015FB307DAD9208A98A2DC3AC4D1448E624B42C89246DCF08692\"\n" +
+ " },\n" +
+ " \"status\": \"success\",\n" +
+ " \"validated\": true\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testOfferResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(41931093)))
+ .ledgerHash(Hash256.of("54FE89D2FF925D623D386A03B402FDB22B2D2D058A62AEE441CA52CC9AA92BB1"))
+ .validated(true)
+ .index(Hash256.of("066B61CF7248A5A08672541077E3C58EAFD1FA52DDF6B4FD93595E16542C0A14"))
+ .node(
+ OfferObject.builder()
+ .account(Address.of("rNdCZMZqHCo5VkrvsmNVt8ZtdpahT7rDKx"))
+ .bookDirectory(Hash256.of("D30EF7A9BFCCEE47AF722871D91E1E21522DF5141CA29AB05B071AFD498D0000"))
+ .bookNode("0")
+ .flags(OfferFlags.of(131072))
+ .ownerNode("0")
+ .previousTransactionId(Hash256.of("9D613D7E1E34DA5BE421E06002441F1E183C0B7B3323E1898FC585144A7C13B1"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(41931065))
+ .sequence(UnsignedInteger.valueOf(41931063))
+ .takerGets(
+ IssuedCurrencyAmount.builder()
+ .currency("USD")
+ .issuer(Address.of("rNdCZMZqHCo5VkrvsmNVt8ZtdpahT7rDKx"))
+ .value("100")
+ .build()
+ )
+ .takerPays(XrpCurrencyAmount.ofDrops(200000000))
+ .index(Hash256.of("066B61CF7248A5A08672541077E3C58EAFD1FA52DDF6B4FD93595E16542C0A14"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"index\": \"066B61CF7248A5A08672541077E3C58EAFD1FA52DDF6B4FD93595E16542C0A14\",\n" +
+ " \"ledger_hash\": \"54FE89D2FF925D623D386A03B402FDB22B2D2D058A62AEE441CA52CC9AA92BB1\",\n" +
+ " \"ledger_index\": 41931093,\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rNdCZMZqHCo5VkrvsmNVt8ZtdpahT7rDKx\",\n" +
+ " \"BookDirectory\": \"D30EF7A9BFCCEE47AF722871D91E1E21522DF5141CA29AB05B071AFD498D0000\",\n" +
+ " \"BookNode\": \"0\",\n" +
+ " \"Flags\": 131072,\n" +
+ " \"LedgerEntryType\": \"Offer\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"PreviousTxnID\": \"9D613D7E1E34DA5BE421E06002441F1E183C0B7B3323E1898FC585144A7C13B1\",\n" +
+ " \"PreviousTxnLgrSeq\": 41931065,\n" +
+ " \"Sequence\": 41931063,\n" +
+ " \"TakerGets\": {\n" +
+ " \"currency\": \"USD\",\n" +
+ " \"issuer\": \"rNdCZMZqHCo5VkrvsmNVt8ZtdpahT7rDKx\",\n" +
+ " \"value\": \"100\"\n" +
+ " },\n" +
+ " \"TakerPays\": \"200000000\",\n" +
+ " \"index\": \"066B61CF7248A5A08672541077E3C58EAFD1FA52DDF6B4FD93595E16542C0A14\"\n" +
+ " },\n" +
+ " \"status\": \"success\",\n" +
+ " \"validated\": true\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testRippleStateResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("6A409D31A016227B74D6A14C307239B2BBBE0CFBFCF7C271BFAF20CAA7A1E6DA"))
+ .node(
+ RippleStateObject.builder()
+ .balance(
+ IssuedCurrencyAmount.builder()
+ .currency("CNY")
+ .issuer(Address.of("rrrrrrrrrrrrrrrrrrrrBZbvji"))
+ .value("0")
+ .build()
+ )
+ .flags(RippleStateFlags.of(2228224))
+ .highLimit(
+ IssuedCurrencyAmount.builder()
+ .currency("CNY")
+ .issuer(Address.of("rHzKtpcB1KC1YuU4PBhk9m2abqrf2kZsfV"))
+ .value("1000000000")
+ .build()
+ )
+ .highNode("0")
+ .lowLimit(
+ IssuedCurrencyAmount.builder()
+ .currency("CNY")
+ .issuer(Address.of("rJ1adrpGS3xsnQMb9Cw54tWJVFPuSdZHK"))
+ .value("0")
+ .build()
+ )
+ .lowNode("2")
+ .previousTransactionId(Hash256.of("9A5E68C795D68665A648A5A05E5BC94AA3681400353236F75139BD102D9406FD"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(69746363))
+ .index(Hash256.of("6A409D31A016227B74D6A14C307239B2BBBE0CFBFCF7C271BFAF20CAA7A1E6DA"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"6A409D31A016227B74D6A14C307239B2BBBE0CFBFCF7C271BFAF20CAA7A1E6DA\",\n" +
+ " \"node\": {\n" +
+ " \"Balance\": {\n" +
+ " \"currency\": \"CNY\",\n" +
+ " \"issuer\": \"rrrrrrrrrrrrrrrrrrrrBZbvji\",\n" +
+ " \"value\": \"0\"\n" +
+ " },\n" +
+ " \"Flags\": 2228224,\n" +
+ " \"HighLimit\": {\n" +
+ " \"currency\": \"CNY\",\n" +
+ " \"issuer\": \"rHzKtpcB1KC1YuU4PBhk9m2abqrf2kZsfV\",\n" +
+ " \"value\": \"1000000000\"\n" +
+ " },\n" +
+ " \"HighNode\": \"0\",\n" +
+ " \"LedgerEntryType\": \"RippleState\",\n" +
+ " \"LowLimit\": {\n" +
+ " \"currency\": \"CNY\",\n" +
+ " \"issuer\": \"rJ1adrpGS3xsnQMb9Cw54tWJVFPuSdZHK\",\n" +
+ " \"value\": \"0\"\n" +
+ " },\n" +
+ " \"LowNode\": \"2\",\n" +
+ " \"PreviousTxnID\": \"9A5E68C795D68665A648A5A05E5BC94AA3681400353236F75139BD102D9406FD\",\n" +
+ " \"PreviousTxnLgrSeq\": 69746363,\n" +
+ " \"index\": \"6A409D31A016227B74D6A14C307239B2BBBE0CFBFCF7C271BFAF20CAA7A1E6DA\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testCheckResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("56B5D2CC81461E339424869D0F5A2F4F24095B74FCD6F79960EF2D5EA10FBE00"))
+ .node(
+ CheckObject.builder()
+ .account(Address.of("rJk8P3yazgCSSvWXavKKCY5Y3tk4UGCiFF"))
+ .destination(Address.of("rHr2n1zVm5nzadgtJY5G2mUYnmWcrxfTbQ"))
+ .destinationNode("0")
+ .invoiceId(Hash256.of("5D059E085A91283DA8F2C1B8DB973994A3250ABDEDB934799A9C3EE243D3DFBD"))
+ .ownerNode("0")
+ .previousTxnId(Hash256.of("7F2DB52CA2D2C600748D7B1DF060964C74BF0219B8EF055DAB151F8A23CA1B09"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(41931458))
+ .sendMax(XrpCurrencyAmount.ofDrops(12345))
+ .sequence(UnsignedInteger.valueOf(41931456))
+ .index(Hash256.of("56B5D2CC81461E339424869D0F5A2F4F24095B74FCD6F79960EF2D5EA10FBE00"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"56B5D2CC81461E339424869D0F5A2F4F24095B74FCD6F79960EF2D5EA10FBE00\",\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rJk8P3yazgCSSvWXavKKCY5Y3tk4UGCiFF\",\n" +
+ " \"Destination\": \"rHr2n1zVm5nzadgtJY5G2mUYnmWcrxfTbQ\",\n" +
+ " \"DestinationNode\": \"0\",\n" +
+ " \"Flags\": 0,\n" +
+ " \"InvoiceID\": \"5D059E085A91283DA8F2C1B8DB973994A3250ABDEDB934799A9C3EE243D3DFBD\",\n" +
+ " \"LedgerEntryType\": \"Check\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"PreviousTxnID\": \"7F2DB52CA2D2C600748D7B1DF060964C74BF0219B8EF055DAB151F8A23CA1B09\",\n" +
+ " \"PreviousTxnLgrSeq\": 41931458,\n" +
+ " \"SendMax\": \"12345\",\n" +
+ " \"Sequence\": 41931456,\n" +
+ " \"index\": \"56B5D2CC81461E339424869D0F5A2F4F24095B74FCD6F79960EF2D5EA10FBE00\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testEscrowResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("ABC67054C15F79FEE9183B44D2E16CA06A1804E023E6A2EDB288F4976B1BFEC5"))
+ .node(
+ EscrowObject.builder()
+ .account(Address.of("rEWt92vANNAghT9CC83DtnDDWZcJEL5gk1"))
+ .amount(XrpCurrencyAmount.ofDrops(123456))
+ .cancelAfter(UnsignedLong.valueOf(750277784))
+ .destination(Address.of("rMuTP1PFEFMVhDYKNBLgmre5YrCzVoCYjm"))
+ .destinationNode("0")
+ .finishAfter(UnsignedLong.valueOf(750277689))
+ .ownerNode("0")
+ .previousTransactionId(Hash256.of("466C5F96809D62385073F6BA43F5A3C217C96C4A493B7F64F6CE5B5B64278AAA"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(41931760))
+ .index(Hash256.of("ABC67054C15F79FEE9183B44D2E16CA06A1804E023E6A2EDB288F4976B1BFEC5"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"ABC67054C15F79FEE9183B44D2E16CA06A1804E023E6A2EDB288F4976B1BFEC5\",\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rEWt92vANNAghT9CC83DtnDDWZcJEL5gk1\",\n" +
+ " \"Amount\": \"123456\",\n" +
+ " \"CancelAfter\": 750277784,\n" +
+ " \"Destination\": \"rMuTP1PFEFMVhDYKNBLgmre5YrCzVoCYjm\",\n" +
+ " \"DestinationNode\": \"0\",\n" +
+ " \"FinishAfter\": 750277689,\n" +
+ " \"Flags\": 0,\n" +
+ " \"LedgerEntryType\": \"Escrow\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"PreviousTxnID\": \"466C5F96809D62385073F6BA43F5A3C217C96C4A493B7F64F6CE5B5B64278AAA\",\n" +
+ " \"PreviousTxnLgrSeq\": 41931760,\n" +
+ " \"index\": \"ABC67054C15F79FEE9183B44D2E16CA06A1804E023E6A2EDB288F4976B1BFEC5\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testPaymentChannelResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("7474D1ED2DE25B055AD3C8473DDD69553ACD7325BF2B15C83D54E743C576C615"))
+ .node(
+ PayChannelObject.builder()
+ .account(Address.of("rtqQepGRnrvaHCDyLHcc8xY7uCTnV1aRT"))
+ .amount(XrpCurrencyAmount.ofDrops(10000))
+ .balance(XrpCurrencyAmount.ofDrops(0))
+ .cancelAfter(UnsignedLong.valueOf(533171558))
+ .destination(Address.of("r4sxKQshFFUvN8xDiP6KsnUKTyFi1un8UQ"))
+ .ownerNode("0")
+ .previousTransactionId(Hash256.of("987A299731B80FF14519FF28F18C14B0C55487133E086EAC895099428D57737C"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(41931835))
+ .publicKey("EDAF1B0148D4FBB6BC0FCDA97C917C0BD831A654EBFD9B7D84FCB13ADE1BCB5C44")
+ .settleDelay(UnsignedLong.ONE)
+ .index(Hash256.of("7474D1ED2DE25B055AD3C8473DDD69553ACD7325BF2B15C83D54E743C576C615"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"7474D1ED2DE25B055AD3C8473DDD69553ACD7325BF2B15C83D54E743C576C615\",\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rtqQepGRnrvaHCDyLHcc8xY7uCTnV1aRT\",\n" +
+ " \"Amount\": \"10000\",\n" +
+ " \"Balance\": \"0\",\n" +
+ " \"CancelAfter\": 533171558,\n" +
+ " \"Destination\": \"r4sxKQshFFUvN8xDiP6KsnUKTyFi1un8UQ\",\n" +
+ " \"Flags\": 0,\n" +
+ " \"LedgerEntryType\": \"PayChannel\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"PreviousTxnID\": \"987A299731B80FF14519FF28F18C14B0C55487133E086EAC895099428D57737C\",\n" +
+ " \"PreviousTxnLgrSeq\": 41931835,\n" +
+ " \"PublicKey\": \"EDAF1B0148D4FBB6BC0FCDA97C917C0BD831A654EBFD9B7D84FCB13ADE1BCB5C44\",\n" +
+ " \"SettleDelay\": 1,\n" +
+ " \"index\": \"7474D1ED2DE25B055AD3C8473DDD69553ACD7325BF2B15C83D54E743C576C615\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testDepositPreAuthResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("4CFA41F0CEB3BBECB0799BCD4E70057A80B98E762AD655D005BE90992E32CDF7"))
+ .node(
+ DepositPreAuthObject.builder()
+ .account(Address.of("rnmLMp1znQHpSM7xKzL1rg9unXiu1o8ptU"))
+ .authorize(Address.of("r4yaMT4QVKFQsyw5sLrJMETe3Wx1L5P9Pe"))
+ .ownerNode("0")
+ .previousTransactionId(Hash256.of("8D2D634EC7E5B4C6BCB5D4DD72575D42A60A11AD91E5A991692E525E6BF463BA"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(41931900))
+ .index(Hash256.of("4CFA41F0CEB3BBECB0799BCD4E70057A80B98E762AD655D005BE90992E32CDF7"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"4CFA41F0CEB3BBECB0799BCD4E70057A80B98E762AD655D005BE90992E32CDF7\",\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rnmLMp1znQHpSM7xKzL1rg9unXiu1o8ptU\",\n" +
+ " \"Authorize\": \"r4yaMT4QVKFQsyw5sLrJMETe3Wx1L5P9Pe\",\n" +
+ " \"Flags\": 0,\n" +
+ " \"LedgerEntryType\": \"DepositPreauth\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"PreviousTxnID\": \"8D2D634EC7E5B4C6BCB5D4DD72575D42A60A11AD91E5A991692E525E6BF463BA\",\n" +
+ " \"PreviousTxnLgrSeq\": 41931900,\n" +
+ " \"index\": \"4CFA41F0CEB3BBECB0799BCD4E70057A80B98E762AD655D005BE90992E32CDF7\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testTicketResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("8A0FB133F2D9875961990CE1F6CBB08120C7BD9B330B5D2C9718DE2A4ABCFC47"))
+ .node(
+ TicketObject.builder()
+ .account(Address.of("rKfyHN2fbAJuHtSc1gStGDxxbq4kf9VPFQ"))
+ .ownerNode("0")
+ .previousTransactionId(Hash256.of("AB5B87765DABF11B9FE5B40506E355532BBE3CF0ADC8C15AF1CD82F4F68CD13D"))
+ .previousTransactionLedgerSequence(UnsignedInteger.valueOf(41932010))
+ .ticketSequence(UnsignedInteger.valueOf(41932009))
+ .index(Hash256.of("8A0FB133F2D9875961990CE1F6CBB08120C7BD9B330B5D2C9718DE2A4ABCFC47"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"8A0FB133F2D9875961990CE1F6CBB08120C7BD9B330B5D2C9718DE2A4ABCFC47\",\n" +
+ " \"node\": {\n" +
+ " \"Account\": \"rKfyHN2fbAJuHtSc1gStGDxxbq4kf9VPFQ\",\n" +
+ " \"Flags\": 0,\n" +
+ " \"LedgerEntryType\": \"Ticket\",\n" +
+ " \"OwnerNode\": \"0\",\n" +
+ " \"PreviousTxnID\": \"AB5B87765DABF11B9FE5B40506E355532BBE3CF0ADC8C15AF1CD82F4F68CD13D\",\n" +
+ " \"PreviousTxnLgrSeq\": 41932010,\n" +
+ " \"TicketSequence\": 41932009,\n" +
+ " \"index\": \"8A0FB133F2D9875961990CE1F6CBB08120C7BD9B330B5D2C9718DE2A4ABCFC47\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testNftPageResult() throws JSONException, JsonProcessingException {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.valueOf(83126482)))
+ .ledgerHash(Hash256.of("995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84"))
+ .validated(true)
+ .index(Hash256.of("4070656F661A60726DBB384E09F6E36B88071072FFFFFFFFFFFFFFFFFFFFFFFF"))
+ .node(
+ NfTokenPageObject.builder()
+ .addNfTokens(
+ NfTokenWrapper.of(
+ NfToken.builder()
+ .nfTokenId(NfTokenId.of("000000004070656F661A60726DBB384E09F6E36B880710720000099A00000000"))
+ .uri(NfTokenUri.of(
+ "697066733A2F2F62616679626569676479727A74357366703775646D376875373675683779323" +
+ "66E6634646675796C71616266336F636C67747179353566627A6469")
+ )
+ .build()
+ )
+ )
+
+ .previousTransactionId(Hash256.of("C94CF5BC9DF78A75997E93C71CDD8A2776E2DF279DD6F394BF4976045D960C4B"))
+ .previousTransactionLedgerSequence(LedgerIndex.of(UnsignedInteger.valueOf(41932089)))
+ .index(Hash256.of("4070656F661A60726DBB384E09F6E36B88071072FFFFFFFFFFFFFFFFFFFFFFFF"))
+ .build()
+ )
+ .status("success")
+ .build();
+
+ String json = "{\n" +
+ " \"ledger_hash\": \"995F5C7565065ED88C251225C15A02C95D6AADD4AC75E199A9234FA8322B5F84\",\n" +
+ " \"ledger_index\": 83126482,\n" +
+ " \"validated\": true,\n" +
+ " \"index\": \"4070656F661A60726DBB384E09F6E36B88071072FFFFFFFFFFFFFFFFFFFFFFFF\",\n" +
+ " \"node\": {\n" +
+ " \"LedgerEntryType\": \"NFTokenPage\",\n" +
+ " \"NFTokens\": [\n" +
+ " {\n" +
+ " \"NFToken\": {\n" +
+ " \"NFTokenID\": \"000000004070656F661A60726DBB384E09F6E36B880710720000099A00000000\",\n" +
+ " \"URI\": \"697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377" +
+ "932366E6634646675796C71616266336F636C67747179353566627A6469\"\n" +
+ " }\n" +
+ " }\n" +
+ " ],\n" +
+ " \"PreviousTxnID\": \"C94CF5BC9DF78A75997E93C71CDD8A2776E2DF279DD6F394BF4976045D960C4B\",\n" +
+ " \"PreviousTxnLgrSeq\": 41932089,\n" +
+ " \"index\": \"4070656F661A60726DBB384E09F6E36B88071072FFFFFFFFFFFFFFFFFFFFFFFF\"\n" +
+ " },\n" +
+ " \"status\": \"success\"\n" +
+ " }";
+
+ assertCanSerializeAndDeserialize(result, json);
+ }
+
+ @Test
+ void testWithHashAndLedgerIndex() {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .node(mock(LedgerObject.class))
+ .ledgerHash(HASH_256)
+ .ledgerIndex(LedgerIndex.of(UnsignedInteger.ONE))
+ .index(HASH_256)
+ .build();
+
+ assertThat(result.ledgerHash()).isNotEmpty().get().isEqualTo(result.ledgerHashSafe());
+ assertThat(result.ledgerIndex()).isNotEmpty().get().isEqualTo(result.ledgerIndexSafe());
+ assertThat(result.ledgerCurrentIndex()).isEmpty();
+ assertThatThrownBy(result::ledgerCurrentIndexSafe)
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessage("Result did not contain a ledgerCurrentIndex.");
+ }
+
+ @Test
+ void testWithLedgerCurrentIndex() {
+ LedgerEntryResult result = LedgerEntryResult.builder()
+ .node(mock(LedgerObject.class))
+ .ledgerCurrentIndex(LedgerIndex.of(UnsignedInteger.ONE))
+ .index(HASH_256)
+ .build();
+
+ assertThat(result.ledgerCurrentIndex()).isNotEmpty().get().isEqualTo(result.ledgerCurrentIndexSafe());
+ assertThat(result.ledgerHash()).isEmpty();
+ assertThat(result.ledgerIndex()).isEmpty();
+ assertThatThrownBy(result::ledgerHashSafe)
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessage("Result did not contain a ledgerHash.");
+ assertThatThrownBy(result::ledgerIndexSafe)
+ .isInstanceOf(IllegalStateException.class)
+ .hasMessage("Result did not contain a ledgerIndex.");
+ }
+}
\ No newline at end of file
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/AmmObjectTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/AmmObjectTest.java
index d6d1bd329..ec28b7e23 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/AmmObjectTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/AmmObjectTest.java
@@ -2,6 +2,7 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.Mockito.mock;
+import static org.xrpl.xrpl4j.crypto.TestConstants.HASH_256;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.primitives.UnsignedInteger;
@@ -37,6 +38,8 @@ void voteSlotsUnwrapped() {
VoteEntryWrapper.of(voteEntry1),
VoteEntryWrapper.of(voteEntry2)
)
+ .index(HASH_256)
+ .ownerNode("0")
.build();
assertThat(ammObject.voteSlotsUnwrapped()).asList()
@@ -97,9 +100,11 @@ void testJson() throws JSONException, JsonProcessingException {
.expiration(UnsignedInteger.valueOf(721870180))
.build()
)
+ .index(HASH_256)
+ .ownerNode("0")
.build();
- String json = "{\n" +
+ String json = String.format("{\n" +
" \"Account\" : \"rE54zDvgnghAoPopCgvtiqWNq3dU5y836S\",\n" +
" \"LedgerEntryType\" : \"AMM\",\n" +
" \"Asset\" : " + objectMapper.writeValueAsString(ammObject.asset()) + "," +
@@ -108,10 +113,12 @@ void testJson() throws JSONException, JsonProcessingException {
" \"Flags\" : 0,\n" +
" \"LPTokenBalance\" : " + objectMapper.writeValueAsString(ammObject.lpTokenBalance()) + "," +
" \"TradingFee\" : 600,\n" +
+ " \"index\" : %s,\n" +
+ " \"OwnerNode\" : \"0\",\n" +
" \"VoteSlots\" : [\n" +
objectMapper.writeValueAsString(ammObject.voteSlots().get(0)) +
" ]\n" +
- "}";
+ "}", HASH_256);
assertCanSerializeAndDeserialize(ammObject, json);
}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/TicketObjectJsonTests.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/TicketObjectJsonTests.java
index 3d2ba457e..3fb25e4a2 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/TicketObjectJsonTests.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/ledger/TicketObjectJsonTests.java
@@ -20,6 +20,8 @@
* =========================LICENSE_END==================================
*/
+import static org.xrpl.xrpl4j.crypto.TestConstants.HASH_256;
+
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.primitives.UnsignedInteger;
import org.json.JSONException;
@@ -38,17 +40,19 @@ void testJson() throws JSONException, JsonProcessingException {
.previousTransactionId(Hash256.of("F19AD4577212D3BEACA0F75FE1BA1644F2E854D46E8D62E9C95D18E9708CBFB1"))
.previousTransactionLedgerSequence(UnsignedInteger.valueOf(4))
.ticketSequence(UnsignedInteger.valueOf(3))
+ .index(HASH_256)
.build();
- String json = "{\n" +
+ String json = String.format("{\n" +
" \"Account\" : \"rEhxGqkqPPSxQ3P25J66ft5TwpzV14k2de\",\n" +
" \"Flags\" : 0,\n" +
" \"LedgerEntryType\" : \"Ticket\",\n" +
" \"OwnerNode\" : \"0000000000000000\",\n" +
" \"PreviousTxnID\" : \"F19AD4577212D3BEACA0F75FE1BA1644F2E854D46E8D62E9C95D18E9708CBFB1\",\n" +
" \"PreviousTxnLgrSeq\" : 4,\n" +
+ " \"index\" : %s,\n" +
" \"TicketSequence\" : 3\n" +
- "}";
+ "}", HASH_256);
assertCanSerializeAndDeserialize(ticketObject, json);
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java
index 0ea468489..18e2e9378 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java
@@ -30,12 +30,17 @@
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
import org.xrpl.xrpl4j.crypto.signing.bc.BcSignatureService;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
import org.xrpl.xrpl4j.model.client.transactions.TransactionResult;
import org.xrpl.xrpl4j.model.flags.AccountRootFlags;
import org.xrpl.xrpl4j.model.flags.AccountSetTransactionFlags;
+import org.xrpl.xrpl4j.model.ledger.AccountRootObject;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
import org.xrpl.xrpl4j.model.transactions.AccountSet.AccountSetFlag;
@@ -59,9 +64,12 @@ public void enableAllAndDisableOne() throws JsonRpcClientErrorException, JsonPro
AccountInfoResult accountInfo = this.scanForResult(
() -> this.getValidatedAccountInfo(keyPair.publicKey().deriveAddress())
);
+
assertThat(accountInfo.status()).isNotEmpty().get().isEqualTo("success");
assertThat(accountInfo.accountData().flags().lsfGlobalFreeze()).isEqualTo(false);
+ assertEntryEqualsAccountInfo(keyPair, accountInfo);
+
UnsignedInteger sequence = accountInfo.accountData().sequence();
//////////////////////
// Set asfAccountTxnID (no corresponding ledger flag)
@@ -384,10 +392,34 @@ void submitAndRetrieveAccountSetWithZeroClearFlagAndSetFlag()
assertThat(accountSetTransactionResult.transaction().clearFlag()).isNotEmpty().get().isEqualTo(AccountSetFlag.NONE);
}
+
//////////////////////
// Test Helpers
//////////////////////
+ private void assertEntryEqualsAccountInfo(
+ KeyPair keyPair,
+ AccountInfoResult accountInfo
+ ) throws JsonRpcClientErrorException {
+ LedgerEntryResult accountRoot = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.accountRoot(keyPair.publicKey().deriveAddress(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(accountInfo.accountData()).isEqualTo(accountRoot.node());
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(accountRoot.index(), AccountRootObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(accountRoot.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(accountRoot.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
+
private void assertSetFlag(
final KeyPair keyPair,
final UnsignedInteger sequence,
@@ -420,12 +452,14 @@ private void assertSetFlag(
/////////////////////////
// Validate Account State
- this.scanForResult(
+ AccountInfoResult accountInfo = this.scanForResult(
() -> this.getValidatedAccountInfo(keyPair.publicKey().deriveAddress()),
accountInfoResult -> {
logger.info("AccountInfoResponse Flags: {}", accountInfoResult.accountData().flags());
return accountInfoResult.accountData().flags().isSet(accountRootFlag);
});
+
+ assertEntryEqualsAccountInfo(keyPair, accountInfo);
}
private void assertClearFlag(
@@ -460,11 +494,13 @@ private void assertClearFlag(
/////////////////////////
// Validate Account State
- this.scanForResult(
+ AccountInfoResult accountInfo = this.scanForResult(
() -> this.getValidatedAccountInfo(keyPair.publicKey().deriveAddress()),
accountInfoResult -> {
logger.info("AccountInfoResponse Flags: {}", accountInfoResult.accountData().flags());
return !accountInfoResult.accountData().flags().isSet(accountRootFlag);
});
+
+ assertEntryEqualsAccountInfo(keyPair, accountInfo);
}
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AmmIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AmmIT.java
index 861930403..074472a7c 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AmmIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AmmIT.java
@@ -6,6 +6,7 @@
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import com.google.common.primitives.UnsignedInteger;
+import com.google.common.primitives.UnsignedLong;
import org.junit.jupiter.api.Test;
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
@@ -18,27 +19,32 @@
import org.xrpl.xrpl4j.model.client.accounts.AccountLinesResult;
import org.xrpl.xrpl4j.model.client.accounts.TrustLine;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoAuctionSlot;
+import org.xrpl.xrpl4j.model.client.amm.AmmInfoAuthAccount;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoRequestParams;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoResult;
-import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
+import org.xrpl.xrpl4j.model.client.common.TimeUtils;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.AmmLedgerEntryParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
import org.xrpl.xrpl4j.model.flags.AmmDepositFlags;
import org.xrpl.xrpl4j.model.flags.AmmWithdrawFlags;
+import org.xrpl.xrpl4j.model.ledger.AmmObject;
+import org.xrpl.xrpl4j.model.ledger.AuctionSlot;
import org.xrpl.xrpl4j.model.ledger.AuthAccount;
import org.xrpl.xrpl4j.model.ledger.AuthAccountWrapper;
import org.xrpl.xrpl4j.model.ledger.Issue;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
import org.xrpl.xrpl4j.model.transactions.AccountSet.AccountSetFlag;
import org.xrpl.xrpl4j.model.transactions.AmmBid;
import org.xrpl.xrpl4j.model.transactions.AmmCreate;
-import org.xrpl.xrpl4j.model.transactions.AmmDelete;
import org.xrpl.xrpl4j.model.transactions.AmmDeposit;
import org.xrpl.xrpl4j.model.transactions.AmmVote;
import org.xrpl.xrpl4j.model.transactions.AmmWithdraw;
-import org.xrpl.xrpl4j.model.transactions.ImmutableAmmWithdraw;
import org.xrpl.xrpl4j.model.transactions.IssuedCurrencyAmount;
import org.xrpl.xrpl4j.model.transactions.TradingFee;
import org.xrpl.xrpl4j.model.transactions.TransactionResultCodes;
@@ -46,6 +52,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.util.stream.Collectors;
public class AmmIT extends AbstractIT {
@@ -405,6 +412,62 @@ private AmmInfoResult getAmmInfo(KeyPair issuerKeyPair) throws JsonRpcClientErro
assertThat(ammInfoByAccount).isEqualTo(ammInfoResult);
+ LedgerEntryResult ammObject = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.amm(
+ AmmLedgerEntryParams.builder()
+ .asset(Issue.XRP)
+ .asset2(
+ Issue.builder()
+ .issuer(issuerKeyPair.publicKey().deriveAddress())
+ .currency(xrpl4jCoin)
+ .build()
+ )
+ .build(),
+ LedgerSpecifier.VALIDATED
+ )
+ );
+
+ assertThat(ammObject.node().account()).isEqualTo(ammInfoByAccount.amm().account());
+ assertThat(ammObject.node().asset()).isEqualTo(Issue.XRP);
+ assertThat(ammObject.node().asset2()).isEqualTo(
+ Issue.builder()
+ .issuer(((IssuedCurrencyAmount) ammInfoByAccount.amm().amount2()).issuer())
+ .currency(((IssuedCurrencyAmount) ammInfoByAccount.amm().amount2()).currency())
+ .build()
+ );
+ assertThat(
+ (ammObject.node().auctionSlot().isPresent() && ammInfoByAccount.amm().auctionSlot().isPresent()) ||
+ (!ammObject.node().auctionSlot().isPresent() && !ammInfoByAccount.amm().auctionSlot().isPresent())
+ ).isTrue();
+ if (ammObject.node().auctionSlot().isPresent()) {
+ AuctionSlot entryAuctionSlot = ammObject.node().auctionSlot().get();
+ AmmInfoAuctionSlot infoAuctionSlot = ammInfoByAccount.amm().auctionSlot().get();
+ assertThat(entryAuctionSlot.account()).isEqualTo(infoAuctionSlot.account());
+ assertThat(entryAuctionSlot.authAccountsAddresses()).isEqualTo(infoAuctionSlot.authAccounts().stream().map(
+ AmmInfoAuthAccount::account).collect(Collectors.toList()));
+ assertThat(entryAuctionSlot.price()).isEqualTo(infoAuctionSlot.price());
+ assertThat(TimeUtils.xrplTimeToZonedDateTime(UnsignedLong.valueOf(entryAuctionSlot.expiration().longValue())))
+ .isEqualTo(infoAuctionSlot.expiration());
+ assertThat(entryAuctionSlot.discountedFee()).isEqualTo(infoAuctionSlot.discountedFee());
+ }
+
+ assertThat(ammObject.node().lpTokenBalance()).isEqualTo(ammInfoByAccount.amm().lpToken());
+ assertThat(ammObject.node().tradingFee()).isEqualTo(ammInfoByAccount.amm().tradingFee());
+
+ assertThat(ammObject.node().voteSlots().size()).isEqualTo(ammInfoByAccount.amm().voteSlots().size());
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(ammObject.index(), AmmObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(ammObject.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(ammObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+
return ammInfoResult;
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/CheckIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/CheckIT.java
index 40928ec6d..5e4b93ee2 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/CheckIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/CheckIT.java
@@ -30,10 +30,14 @@
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
import org.xrpl.xrpl4j.model.ledger.CheckObject;
+import org.xrpl.xrpl4j.model.ledger.EscrowObject;
import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.transactions.CheckCancel;
import org.xrpl.xrpl4j.model.transactions.CheckCash;
@@ -97,6 +101,8 @@ public void createXrpCheckAndCash() throws JsonRpcClientErrorException, JsonProc
.filter(findCheck(sourceKeyPair, destinationKeyPair, invoiceId))
.findFirst().get();
+ assertEntryEqualsObjectFromAccountObjects(checkObject);
+
//////////////////////
// Destination wallet cashes the Check
feeResult = xrplClient.fee();
@@ -188,6 +194,8 @@ public void createCheckAndSourceCancels() throws JsonRpcClientErrorException, Js
.filter(findCheck(sourceKeyPair, destinationKeyPair, invoiceId))
.findFirst().get();
+ assertEntryEqualsObjectFromAccountObjects(checkObject);
+
//////////////////////
// Source account cancels the Check
feeResult = xrplClient.fee();
@@ -265,6 +273,8 @@ public void createCheckAndDestinationCancels() throws JsonRpcClientErrorExceptio
.filter(findCheck(sourceKeyPair, destinationKeyPair, invoiceId))
.findFirst().get();
+ assertEntryEqualsObjectFromAccountObjects(checkObject);
+
//////////////////////
// Destination account cancels the Check
feeResult = xrplClient.fee();
@@ -304,4 +314,23 @@ private Predicate findCheck(KeyPair sourceKeyPair, KeyPair destina
((CheckObject) object).destination().equals(destinationKeyPair.publicKey().deriveAddress());
}
+
+ private void assertEntryEqualsObjectFromAccountObjects(CheckObject checkObject) throws JsonRpcClientErrorException {
+ LedgerEntryResult checkEntry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.check(checkObject.index(), LedgerSpecifier.CURRENT));
+
+ assertThat(checkEntry.node()).isEqualTo(checkObject);
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(checkObject.index(), CheckObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(checkEntry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(checkObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/DepositPreAuthIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/DepositPreAuthIT.java
index 28c86519e..5b9c2d618 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/DepositPreAuthIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/DepositPreAuthIT.java
@@ -33,10 +33,16 @@
import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.DepositPreAuthLedgerEntryParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.path.DepositAuthorizedRequestParams;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
import org.xrpl.xrpl4j.model.client.transactions.TransactionResult;
+import org.xrpl.xrpl4j.model.ledger.CheckObject;
import org.xrpl.xrpl4j.model.ledger.DepositPreAuthObject;
+import org.xrpl.xrpl4j.model.ledger.EscrowObject;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
import org.xrpl.xrpl4j.model.transactions.DepositPreAuth;
import org.xrpl.xrpl4j.model.transactions.Hash256;
@@ -85,14 +91,20 @@ public void preauthorizeAccountAndReceivePayment() throws JsonRpcClientErrorExce
/////////////////////////
// Validate that the DepositPreAuthObject was added to the receiver's account objects
- this.scanForResult(
+ DepositPreAuthObject preAuthObject = (DepositPreAuthObject) this.scanForResult(
() -> this.getValidatedAccountObjects(receiverKeyPair.publicKey().deriveAddress()),
accountObjects ->
accountObjects.accountObjects().stream().anyMatch(object ->
DepositPreAuthObject.class.isAssignableFrom(object.getClass()) &&
((DepositPreAuthObject) object).authorize().equals(senderKeyPair.publicKey().deriveAddress())
)
- );
+ ).accountObjects().stream()
+ .filter(object -> DepositPreAuthObject.class.isAssignableFrom(object.getClass()) &&
+ ((DepositPreAuthObject) object).authorize().equals(senderKeyPair.publicKey().deriveAddress()))
+ .findFirst()
+ .get();
+
+ assertEntryEqualsObjectFromAccountObjects(depositPreAuth, preAuthObject);
/////////////////////////
// Validate that the `deposit_authorized` client call is implemented properly by ensuring it aligns with the
@@ -266,4 +278,34 @@ private AccountInfoResult enableDepositPreauth(
accountInfo -> accountInfo.accountData().flags().lsfDepositAuth()
);
}
+
+ private void assertEntryEqualsObjectFromAccountObjects(
+ DepositPreAuth depositPreAuth,
+ DepositPreAuthObject preAuthObject
+ )
+ throws JsonRpcClientErrorException {
+ LedgerEntryResult preAuthEntry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.depositPreAuth(
+ DepositPreAuthLedgerEntryParams.builder()
+ .owner(depositPreAuth.account())
+ .authorized(depositPreAuth.authorize().get())
+ .build(),
+ LedgerSpecifier.CURRENT
+ )
+ );
+
+ assertThat(preAuthEntry.node()).isEqualTo(preAuthObject);
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(preAuthObject.index(), DepositPreAuthObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(preAuthEntry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(preAuthObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/EscrowIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/EscrowIT.java
index fed3ba8a9..5d34919b7 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/EscrowIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/EscrowIT.java
@@ -9,9 +9,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,16 +27,25 @@
import com.google.common.primitives.UnsignedLong;
import com.ripple.cryptoconditions.PreimageSha256Fulfillment;
import org.junit.jupiter.api.Test;
+import org.testcontainers.shaded.com.github.dockerjava.core.dockerfile.DockerfileStatement.Add;
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.accounts.AccountObjectsRequestParams;
+import org.xrpl.xrpl4j.model.client.accounts.AccountObjectsRequestParams.AccountObjectType;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
+import org.xrpl.xrpl4j.model.client.ledger.EscrowLedgerEntryParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.ledger.LedgerResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
import org.xrpl.xrpl4j.model.client.transactions.TransactionResult;
import org.xrpl.xrpl4j.model.immutables.FluentCompareTo;
import org.xrpl.xrpl4j.model.ledger.EscrowObject;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
+import org.xrpl.xrpl4j.model.transactions.Address;
import org.xrpl.xrpl4j.model.transactions.EscrowCancel;
import org.xrpl.xrpl4j.model.transactions.EscrowCreate;
import org.xrpl.xrpl4j.model.transactions.EscrowFinish;
@@ -92,6 +101,11 @@ public void createAndFinishTimeBasedEscrow() throws JsonRpcClientErrorException,
() -> this.getValidatedTransaction(createResult.transactionResult().hash(), EscrowCreate.class)
);
+ assertEntryEqualsObjectFromAccountObjects(
+ senderKeyPair.publicKey().deriveAddress(),
+ escrowCreate.sequence()
+ );
+
//////////////////////
// Wait until the close time on the current validated ledger is after the finishAfter time on the Escrow
this.scanForResult(
@@ -188,7 +202,7 @@ public void createAndCancelTimeBasedEscrow() throws JsonRpcClientErrorException,
//////////////////////
// Then wait until the transaction gets committed to a validated ledger
- TransactionResult result = this.scanForResult(
+ final TransactionResult result = this.scanForResult(
() -> this.getValidatedTransaction(createResult.transactionResult().hash(), EscrowCreate.class)
);
@@ -201,6 +215,11 @@ public void createAndCancelTimeBasedEscrow() throws JsonRpcClientErrorException,
)
);
+ assertEntryEqualsObjectFromAccountObjects(
+ senderKeyPair.publicKey().deriveAddress(),
+ escrowCreate.sequence()
+ );
+
//////////////////////
// Wait until the close time on the current validated ledger is after the cancelAfter time on the Escrow
this.scanForResult(
@@ -298,6 +317,11 @@ public void createAndFinishCryptoConditionBasedEscrow() throws JsonRpcClientErro
() -> this.getValidatedTransaction(createResult.transactionResult().hash(), EscrowCreate.class)
);
+ assertEntryEqualsObjectFromAccountObjects(
+ senderKeyPair.publicKey().deriveAddress(),
+ escrowCreate.sequence()
+ );
+
//////////////////////
// Wait until the close time on the current validated ledger is after the finishAfter time on the Escrow
this.scanForResult(
@@ -405,6 +429,11 @@ public void createAndCancelCryptoConditionBasedEscrow() throws JsonRpcClientErro
() -> this.getValidatedTransaction(createResult.transactionResult().hash(), EscrowCreate.class)
);
+ assertEntryEqualsObjectFromAccountObjects(
+ senderKeyPair.publicKey().deriveAddress(),
+ escrowCreate.sequence()
+ );
+
//////////////////////
// Wait until the close time on the current validated ledger is after the cancelAfter time on the Escrow
this.scanForResult(
@@ -475,4 +504,41 @@ private Instant getMinExpirationTime() {
return closeTime.isBefore(now) ? now : closeTime;
}
+
+ private void assertEntryEqualsObjectFromAccountObjects(
+ Address escrowOwner,
+ UnsignedInteger createSequence
+ ) throws JsonRpcClientErrorException {
+
+ EscrowObject escrowObject = (EscrowObject) xrplClient.accountObjects(AccountObjectsRequestParams.builder()
+ .type(AccountObjectType.ESCROW)
+ .account(escrowOwner)
+ .ledgerSpecifier(LedgerSpecifier.VALIDATED)
+ .build()
+ ).accountObjects().get(0);
+
+ LedgerEntryResult escrowEntry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.escrow(
+ EscrowLedgerEntryParams.builder()
+ .owner(escrowOwner)
+ .seq(createSequence)
+ .build(),
+ LedgerSpecifier.VALIDATED
+ )
+ );
+
+ assertThat(escrowEntry.node()).isEqualTo(escrowObject);
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(escrowObject.index(), EscrowObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(escrowEntry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(escrowObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/IssuedCurrencyIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/IssuedCurrencyIT.java
index 17f84fa61..670135a9a 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/IssuedCurrencyIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/IssuedCurrencyIT.java
@@ -25,6 +25,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
+import com.google.common.primitives.UnsignedInteger;
import org.junit.jupiter.api.Test;
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
@@ -32,12 +33,21 @@
import org.xrpl.xrpl4j.model.client.accounts.AccountCurrenciesRequestParams;
import org.xrpl.xrpl4j.model.client.accounts.AccountCurrenciesResult;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.accounts.AccountObjectsRequestParams;
import org.xrpl.xrpl4j.model.client.accounts.TrustLine;
import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
+import org.xrpl.xrpl4j.model.client.ledger.RippleStateLedgerEntryParams;
+import org.xrpl.xrpl4j.model.client.ledger.RippleStateLedgerEntryParams.RippleStateAccounts;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
+import org.xrpl.xrpl4j.model.ledger.EscrowObject;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
+import org.xrpl.xrpl4j.model.ledger.RippleStateObject;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
+import org.xrpl.xrpl4j.model.transactions.Address;
import org.xrpl.xrpl4j.model.transactions.IssuedCurrencyAmount;
import org.xrpl.xrpl4j.model.transactions.PathStep;
import org.xrpl.xrpl4j.model.transactions.Payment;
@@ -77,6 +87,12 @@ void createTrustlineWithMaxLimit() throws JsonRpcClientErrorException, JsonProce
FeeUtils.computeNetworkFees(feeResult).recommendedFee()
);
+ assertThatEntryEqualsObjectFromAccountObjects(
+ trustLine,
+ issuerKeyPair.publicKey().deriveAddress(),
+ xrpl4jCoin
+ );
+
assertThat(trustLine.limitPeer()).isEqualTo("9999999999999999e80");
}
@@ -102,6 +118,12 @@ void createTrustlineWithMaxLimitMinusOneExponent() throws JsonRpcClientErrorExce
FeeUtils.computeNetworkFees(feeResult).recommendedFee()
);
+ assertThatEntryEqualsObjectFromAccountObjects(
+ trustLine,
+ issuerKeyPair.publicKey().deriveAddress(),
+ xrpl4jCoin
+ );
+
assertThat(trustLine.limitPeer()).isEqualTo("9999999999999999e79");
}
@@ -127,6 +149,12 @@ void createTrustlineWithSmallestPositiveLimit() throws JsonRpcClientErrorExcepti
FeeUtils.computeNetworkFees(feeResult).recommendedFee()
);
+ assertThatEntryEqualsObjectFromAccountObjects(
+ trustLine,
+ issuerKeyPair.publicKey().deriveAddress(),
+ xrpl4jCoin
+ );
+
assertThat(trustLine.limitPeer()).isEqualTo("1000000000000000e-96");
}
@@ -154,6 +182,12 @@ void createTrustlineWithSmalletPositiveLimitPlusOne() throws JsonRpcClientErrorE
FeeUtils.computeNetworkFees(feeResult).recommendedFee()
);
+ assertThatEntryEqualsObjectFromAccountObjects(
+ trustLine,
+ issuerKeyPair.publicKey().deriveAddress(),
+ xrpl4jCoin
+ );
+
assertThat(trustLine.limitPeer()).isEqualTo("1100000000000000e-96");
}
@@ -179,6 +213,12 @@ public void issueIssuedCurrencyBalance() throws JsonRpcClientErrorException, Jso
FeeUtils.computeNetworkFees(feeResult).recommendedFee()
);
+ assertThatEntryEqualsObjectFromAccountObjects(
+ trustLine,
+ issuerKeyPair.publicKey().deriveAddress(),
+ xrpl4jCoin
+ );
+
///////////////////////////
// Send some xrpl4jCoin to the counterparty account.
sendIssuedCurrency(
@@ -189,9 +229,19 @@ public void issueIssuedCurrencyBalance() throws JsonRpcClientErrorException, Jso
///////////////////////////
// Validate that the TrustLine balance was updated as a result of the Payment.
// The trust line returned is from the perspective of the issuer, so the balance should be negative.
- this.scanForResult(() -> getValidatedAccountLines(issuerKeyPair.publicKey().deriveAddress(),
- counterpartyKeyPair.publicKey().deriveAddress()),
+ TrustLine trustLineAfterPayment = this.scanForResult(
+ () -> getValidatedAccountLines(issuerKeyPair.publicKey().deriveAddress(),
+ counterpartyKeyPair.publicKey().deriveAddress()),
linesResult -> linesResult.lines().stream().anyMatch(line -> line.balance().equals("-" + trustLine.limitPeer()))
+ ).lines().stream()
+ .filter(line -> line.balance().equals("-" + trustLine.limitPeer()))
+ .findFirst()
+ .get();
+
+ assertThatEntryEqualsObjectFromAccountObjects(
+ trustLineAfterPayment,
+ issuerKeyPair.publicKey().deriveAddress(),
+ xrpl4jCoin
);
///////////////////////////
@@ -559,4 +609,42 @@ public void setDefaultRipple(KeyPair issuerKeyPair, FeeResult feeResult)
);
}
+
+ private void assertThatEntryEqualsObjectFromAccountObjects(
+ TrustLine trustLine,
+ Address peerAddress,
+ String currency
+ ) throws JsonRpcClientErrorException {
+ RippleStateObject rippleStateObject = (RippleStateObject) xrplClient.accountObjects(
+ AccountObjectsRequestParams.of(trustLine.account())
+ ).accountObjects().stream()
+ .filter(object -> RippleStateObject.class.isAssignableFrom(object.getClass()) /*&&*/
+ /*((RippleStateObject) object).previousTransactionLedgerSequence().equals(lastSequence)*/)
+ .findFirst()
+ .get();
+
+ LedgerEntryResult entry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.rippleState(
+ RippleStateLedgerEntryParams.builder()
+ .accounts(RippleStateAccounts.of(trustLine.account(), peerAddress))
+ .currency(currency)
+ .build(),
+ LedgerSpecifier.VALIDATED
+ )
+ );
+
+ assertThat(entry.node()).isEqualTo(rippleStateObject);
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(rippleStateObject.index(), RippleStateObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(rippleStateObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java
index cc0a143d2..5204f08f8 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java
@@ -26,6 +26,7 @@
import com.google.common.collect.Lists;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLong;
+import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
@@ -34,9 +35,11 @@
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
import org.xrpl.xrpl4j.model.client.accounts.AccountNftsResult;
import org.xrpl.xrpl4j.model.client.accounts.AccountObjectsRequestParams;
-import org.xrpl.xrpl4j.model.client.accounts.AccountObjectsResult;
import org.xrpl.xrpl4j.model.client.accounts.NfTokenObject;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.nft.NftBuyOffersRequestParams;
import org.xrpl.xrpl4j.model.client.nft.NftBuyOffersResult;
import org.xrpl.xrpl4j.model.client.nft.NftSellOffersRequestParams;
@@ -112,7 +115,7 @@ void mint() throws JsonRpcClientErrorException, JsonProcessingException {
},
result -> result.accountNfts().stream()
.anyMatch(nft -> nft.uri().get().equals(uri))
- )
+ )
.accountNfts()
.stream().filter(nft -> nft.uri().get().equals(uri))
.findFirst()
@@ -121,22 +124,7 @@ void mint() throws JsonRpcClientErrorException, JsonProcessingException {
assertThat(validatedMint.metadata().flatMap(TransactionMetadata::nfTokenId))
.isNotEmpty().get().isEqualTo(nfToken.nfTokenId());
- Optional maybeNfTokenPage = xrplClient.accountObjects(
- AccountObjectsRequestParams.of(nfTokenMint.account())
- ).accountObjects().stream()
- .filter(object -> NfTokenPageObject.class.isAssignableFrom(object.getClass()))
- .map(object -> (NfTokenPageObject) object)
- .findFirst();
-
- assertThat(maybeNfTokenPage).isNotEmpty();
- assertThat(maybeNfTokenPage.get().nfTokens()).contains(
- NfTokenWrapper.of(
- NfToken.builder()
- .nfTokenId(nfToken.nfTokenId())
- .uri(nfToken.uri())
- .build()
- )
- );
+ assertEntryEqualsObjectFromAccountObjects(keyPair.publicKey().deriveAddress(), nfToken);
AccountInfoResult minterAccountInfo = xrplClient.accountInfo(
AccountInfoRequestParams.of(keyPair.publicKey().deriveAddress())
@@ -198,18 +186,9 @@ void mintFromOtherMinterAccount() throws JsonRpcClientErrorException, JsonProces
assertThat(mintSubmitResult.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
assertThat(signedMint.hash()).isEqualTo(mintSubmitResult.transactionResult().hash());
- this.scanForResult(
- () -> {
- try {
- return xrplClient.accountNfts(minterKeyPair.publicKey().deriveAddress());
- } catch (JsonRpcClientErrorException e) {
- logger.error("Exception occurred while getting account nfts: {}", e.getMessage(), e);
- throw new RuntimeException(e);
- }
- },
- result -> result.accountNfts().stream()
- .anyMatch(nft -> nft.uri().get().equals(uri))
- );
+ NfTokenObject nfToken = scanForNfToken(minterKeyPair, uri);
+
+ assertEntryEqualsObjectFromAccountObjects(minterKeyPair.publicKey().deriveAddress(), nfToken);
AccountInfoResult sourceAccountInfoAfterMint = xrplClient.accountInfo(
AccountInfoRequestParams.of(keyPair.publicKey().deriveAddress())
@@ -247,19 +226,11 @@ void mintAndBurn() throws JsonRpcClientErrorException, JsonProcessingException {
assertThat(mintSubmitResult.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
assertThat(signedMint.hash()).isEqualTo(mintSubmitResult.transactionResult().hash());
- this.scanForResult(
- () -> {
- try {
- return xrplClient.accountNfts(keyPair.publicKey().deriveAddress());
- } catch (JsonRpcClientErrorException e) {
- throw new RuntimeException(e);
- }
- },
- result -> result.accountNfts().stream()
- .anyMatch(nft -> nft.uri().get().equals(uri))
- );
+ NfTokenObject nfToken = scanForNfToken(keyPair, uri);
logger.info("NFT was minted successfully.");
+ assertEntryEqualsObjectFromAccountObjects(keyPair.publicKey().deriveAddress(), nfToken);
+
// nft burn
AccountNftsResult accountNftsResult = xrplClient.accountNfts(keyPair.publicKey().deriveAddress());
@@ -335,19 +306,11 @@ void mintAndCreateOffer() throws JsonRpcClientErrorException, JsonProcessingExce
mintSubmitResult.transactionResult().hash()
);
- this.scanForResult(
- () -> {
- try {
- return xrplClient.accountNfts(keyPair.publicKey().deriveAddress());
- } catch (JsonRpcClientErrorException e) {
- throw new RuntimeException(e);
- }
- },
- result -> result.accountNfts().stream()
- .anyMatch(nft -> nft.uri().get().equals(uri))
- );
+ NfTokenObject nfToken = scanForNfToken(keyPair, uri);
logger.info("NFT was minted successfully.");
+ assertEntryEqualsObjectFromAccountObjects(keyPair.publicKey().deriveAddress(), nfToken);
+
//create a sell offer for the NFT that was created above
NfTokenId tokenId = xrplClient.accountNfts(keyPair.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
@@ -394,6 +357,12 @@ void mintAndCreateOffer() throws JsonRpcClientErrorException, JsonProcessingExce
.findFirst()
.get();
+ LedgerEntryResult entry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(nfTokenOffer.index(), NfTokenOfferObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entry.node()).isEqualTo(nfTokenOffer);
+
assertThat(validatedOfferCreate.metadata().flatMap(TransactionMetadata::offerId)).isNotEmpty().get()
.isEqualTo(nfTokenOffer.index());
logger.info("NFTokenOffer object was found in account's objects.");
@@ -401,20 +370,20 @@ void mintAndCreateOffer() throws JsonRpcClientErrorException, JsonProcessingExce
@Test
void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProcessingException {
- KeyPair wallet = createRandomAccountEd25519();
+ KeyPair keypair = createRandomAccountEd25519();
//mint NFT from one account
AccountInfoResult accountInfoResult = this.scanForResult(
- () -> this.getValidatedAccountInfo(wallet.publicKey().deriveAddress())
+ () -> this.getValidatedAccountInfo(keypair.publicKey().deriveAddress())
);
NfTokenUri uri = NfTokenUri.ofPlainText("ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi");
//Nft mint transaction
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.fee(XrpCurrencyAmount.ofDrops(50))
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.flags(NfTokenMintFlags.builder()
.tfTransferable(true)
@@ -422,27 +391,19 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
.uri(uri)
.build();
- SingleSignedTransaction signedMint = signatureService.sign(wallet.privateKey(), nfTokenMint);
+ SingleSignedTransaction signedMint = signatureService.sign(keypair.privateKey(), nfTokenMint);
SubmitResult mintSubmitResult = xrplClient.submit(signedMint);
assertThat(mintSubmitResult.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
assertThat(signedMint.hash()).isEqualTo(mintSubmitResult.transactionResult().hash());
- this.scanForResult(
- () -> {
- try {
- return xrplClient.accountNfts(wallet.publicKey().deriveAddress());
- } catch (JsonRpcClientErrorException e) {
- throw new RuntimeException(e);
- }
- },
- result -> result.accountNfts().stream()
- .anyMatch(nft -> nft.uri().get().equals(uri))
- );
+ NfTokenObject nfToken = scanForNfToken(keypair, uri);
logger.info("NFT was minted successfully.");
+ assertEntryEqualsObjectFromAccountObjects(keypair.publicKey().deriveAddress(), nfToken);
+
//create a sell offer for the NFT that was created above
- NfTokenId tokenId = xrplClient.accountNfts(wallet.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
+ NfTokenId tokenId = xrplClient.accountNfts(keypair.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
// create buy offer from another account
KeyPair wallet2 = createRandomAccountEd25519();
@@ -453,7 +414,7 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
NfTokenCreateOffer nfTokenCreateOffer = NfTokenCreateOffer.builder()
.account(wallet2.publicKey().deriveAddress())
- .owner(wallet.publicKey().deriveAddress())
+ .owner(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
.fee(XrpCurrencyAmount.ofDrops(50))
.sequence(accountInfoResult2.accountData().sequence())
@@ -478,14 +439,26 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
);
logger.info("NFT Create Offer (Buy) transaction was validated successfully.");
- this.scanForResult(
+ NfTokenOfferObject nfTokenOffer = (NfTokenOfferObject) this.scanForResult(
() -> this.getValidatedAccountObjects(wallet2.publicKey().deriveAddress()),
objectsResult -> objectsResult.accountObjects().stream()
.anyMatch(object ->
NfTokenOfferObject.class.isAssignableFrom(object.getClass()) &&
((NfTokenOfferObject) object).owner().equals(wallet2.publicKey().deriveAddress())
)
+ ).accountObjects()
+ .stream()
+ .filter(object -> NfTokenOfferObject.class.isAssignableFrom(object.getClass()) &&
+ ((NfTokenOfferObject) object).owner().equals(wallet2.publicKey().deriveAddress()))
+ .findFirst()
+ .get();
+
+ LedgerEntryResult entry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(nfTokenOffer.index(), NfTokenOfferObject.class, LedgerSpecifier.VALIDATED)
);
+
+ assertThat(entry.node()).isEqualTo(nfTokenOffer);
+
logger.info("NFTokenOffer object was found in account's objects.");
NftBuyOffersResult nftBuyOffersResult = xrplClient.nftBuyOffers(NftBuyOffersRequestParams.builder()
@@ -495,15 +468,15 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
// accept offer from a different account
NfTokenAcceptOffer nfTokenAcceptOffer = NfTokenAcceptOffer.builder()
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.buyOffer(nftBuyOffersResult.offers().get(0).nftOfferIndex())
.fee(XrpCurrencyAmount.ofDrops(50))
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.build();
SingleSignedTransaction signedAccept = signatureService.sign(
- wallet.privateKey(),
+ keypair.privateKey(),
nfTokenAcceptOffer
);
SubmitResult nfTokenAcceptOfferSubmitResult = xrplClient.submit(signedAccept);
@@ -518,7 +491,7 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
);
logger.info("NFT Accept Offer transaction was validated successfully.");
- assertThat(xrplClient.accountNfts(wallet.publicKey().deriveAddress()).accountNfts().size()).isEqualTo(0);
+ assertThat(xrplClient.accountNfts(keypair.publicKey().deriveAddress()).accountNfts().size()).isEqualTo(0);
assertThat(xrplClient.accountNfts(wallet2.publicKey().deriveAddress()).accountNfts().size()).isEqualTo(1);
logger.info("The NFT ownership was transferred.");
@@ -526,58 +499,49 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
@Test
void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, JsonProcessingException {
- KeyPair wallet = createRandomAccountEd25519();
+ KeyPair keypair = createRandomAccountEd25519();
//mint NFT from one account
AccountInfoResult accountInfoResult = this.scanForResult(
- () -> this.getValidatedAccountInfo(wallet.publicKey().deriveAddress())
+ () -> this.getValidatedAccountInfo(keypair.publicKey().deriveAddress())
);
NfTokenUri uri = NfTokenUri.ofPlainText("ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi");
//Nft mint transaction
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.fee(XrpCurrencyAmount.ofDrops(50))
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.uri(uri)
.build();
- SingleSignedTransaction signedMint = signatureService.sign(wallet.privateKey(), nfTokenMint);
+ SingleSignedTransaction signedMint = signatureService.sign(keypair.privateKey(), nfTokenMint);
SubmitResult mintSubmitResult = xrplClient.submit(signedMint);
assertThat(mintSubmitResult.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
assertThat(signedMint.hash()).isEqualTo(mintSubmitResult.transactionResult().hash());
- this.scanForResult(
- () -> {
- try {
- return xrplClient.accountNfts(wallet.publicKey().deriveAddress());
- } catch (JsonRpcClientErrorException e) {
- throw new RuntimeException(e);
- }
- },
- result -> result.accountNfts().stream()
- .anyMatch(nft -> nft.uri().get().equals(uri))
- );
+ scanForNfToken(keypair, uri);
+
logger.info("NFT was minted successfully.");
//create a sell offer for the NFT that was created above
- NfTokenId tokenId = xrplClient.accountNfts(wallet.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
+ NfTokenId tokenId = xrplClient.accountNfts(keypair.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
NfTokenCreateOffer nfTokenCreateOffer = NfTokenCreateOffer.builder()
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
.fee(XrpCurrencyAmount.ofDrops(50))
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.amount(XrpCurrencyAmount.ofDrops(1000))
.flags(NfTokenCreateOfferFlags.SELL_NFTOKEN)
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.build();
SingleSignedTransaction signedOffer = signatureService.sign(
- wallet.privateKey(),
+ keypair.privateKey(),
nfTokenCreateOffer
);
SubmitResult nfTokenCreateOfferSubmitResult = xrplClient.submit(signedOffer);
@@ -594,11 +558,11 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
logger.info("NFT Create Offer (Sell) transaction was validated successfully.");
this.scanForResult(
- () -> this.getValidatedAccountObjects(wallet.publicKey().deriveAddress()),
+ () -> this.getValidatedAccountObjects(keypair.publicKey().deriveAddress()),
objectsResult -> objectsResult.accountObjects().stream()
.anyMatch(object ->
NfTokenOfferObject.class.isAssignableFrom(object.getClass()) &&
- ((NfTokenOfferObject) object).owner().equals(wallet.publicKey().deriveAddress())
+ ((NfTokenOfferObject) object).owner().equals(keypair.publicKey().deriveAddress())
)
);
logger.info("NFTokenOffer object was found in account's objects.");
@@ -610,14 +574,14 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
// cancel the created offer
NfTokenCancelOffer nfTokenCancelOffer = NfTokenCancelOffer.builder()
.addTokenOffers(nftSellOffersResult.offers().get(0).nftOfferIndex())
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.fee(XrpCurrencyAmount.ofDrops(50))
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.valueOf(2)))
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.build();
SingleSignedTransaction signedCancel = signatureService.sign(
- wallet.privateKey(),
+ keypair.privateKey(),
nfTokenCancelOffer
);
SubmitResult nfTokenCancelOfferSubmitResult = xrplClient.submit(signedCancel);
@@ -637,7 +601,7 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
.isEqualTo(Lists.newArrayList(tokenId));
this.scanForResult(
- () -> this.getValidatedAccountObjects(wallet.publicKey().deriveAddress()),
+ () -> this.getValidatedAccountObjects(keypair.publicKey().deriveAddress()),
objectsResult -> objectsResult.accountObjects().stream()
.noneMatch(object ->
NfTokenOfferObject.class.isAssignableFrom(object.getClass())
@@ -648,20 +612,20 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
@Test
void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, JsonProcessingException {
- KeyPair wallet = createRandomAccountEd25519();
+ KeyPair keypair = createRandomAccountEd25519();
//mint NFT from one account
AccountInfoResult accountInfoResult = this.scanForResult(
- () -> this.getValidatedAccountInfo(wallet.publicKey().deriveAddress())
+ () -> this.getValidatedAccountInfo(keypair.publicKey().deriveAddress())
);
NfTokenUri uri = NfTokenUri.ofPlainText("ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi");
//Nft mint transaction
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.fee(XrpCurrencyAmount.ofDrops(50))
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.flags(NfTokenMintFlags.builder()
.tfTransferable(true)
@@ -669,41 +633,32 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
.uri(uri)
.build();
- SingleSignedTransaction signedMint = signatureService.sign(wallet.privateKey(), nfTokenMint);
+ SingleSignedTransaction signedMint = signatureService.sign(keypair.privateKey(), nfTokenMint);
SubmitResult mintSubmitResult = xrplClient.submit(signedMint);
assertThat(mintSubmitResult.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
assertThat(signedMint.hash()).isEqualTo(mintSubmitResult.transactionResult().hash());
- this.scanForResult(
- () -> {
- try {
- return xrplClient.accountNfts(wallet.publicKey().deriveAddress());
- } catch (JsonRpcClientErrorException e) {
- throw new RuntimeException(e);
- }
- },
- result -> result.accountNfts().stream()
- .anyMatch(nft -> nft.uri().get().equals(uri))
- );
+ scanForNfToken(keypair, uri);
+
logger.info("NFT was minted successfully.");
//create a sell offer for the NFT that was created above
- NfTokenId tokenId = xrplClient.accountNfts(wallet.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
+ NfTokenId tokenId = xrplClient.accountNfts(keypair.publicKey().deriveAddress()).accountNfts().get(0).nfTokenId();
// the owner creates the sell offer
NfTokenCreateOffer nfTokenCreateSellOffer = NfTokenCreateOffer.builder()
- .account(wallet.publicKey().deriveAddress())
+ .account(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
.fee(XrpCurrencyAmount.ofDrops(50))
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.amount(XrpCurrencyAmount.ofDrops(1000))
- .signingPublicKey(wallet.publicKey())
+ .signingPublicKey(keypair.publicKey())
.flags(NfTokenCreateOfferFlags.SELL_NFTOKEN)
.build();
SingleSignedTransaction signedOffer = signatureService.sign(
- wallet.privateKey(),
+ keypair.privateKey(),
nfTokenCreateSellOffer
);
SubmitResult nfTokenCreateSellOfferSubmitResult = xrplClient.submit(signedOffer);
@@ -720,11 +675,11 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
logger.info("NFT Create Offer (Sell) transaction was validated successfully.");
this.scanForResult(
- () -> this.getValidatedAccountObjects(wallet.publicKey().deriveAddress()),
+ () -> this.getValidatedAccountObjects(keypair.publicKey().deriveAddress()),
objectsResult -> objectsResult.accountObjects().stream()
.anyMatch(object ->
NfTokenOfferObject.class.isAssignableFrom(object.getClass()) &&
- ((NfTokenOfferObject) object).owner().equals(wallet.publicKey().deriveAddress())
+ ((NfTokenOfferObject) object).owner().equals(keypair.publicKey().deriveAddress())
)
);
logger.info("NFTokenOffer object was found in account's objects.");
@@ -735,24 +690,24 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
assertThat(nftSellOffersResult.offers().size()).isEqualTo(1);
// create buy offer from another account
- KeyPair wallet2 = createRandomAccountEd25519();
+ KeyPair keypair2 = createRandomAccountEd25519();
AccountInfoResult accountInfoResult2 = this.scanForResult(
- () -> this.getValidatedAccountInfo(wallet2.publicKey().deriveAddress())
+ () -> this.getValidatedAccountInfo(keypair2.publicKey().deriveAddress())
);
NfTokenCreateOffer nfTokenCreateOffer = NfTokenCreateOffer.builder()
- .account(wallet2.publicKey().deriveAddress())
- .owner(wallet.publicKey().deriveAddress())
+ .account(keypair2.publicKey().deriveAddress())
+ .owner(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
.fee(XrpCurrencyAmount.ofDrops(50))
.sequence(accountInfoResult2.accountData().sequence())
.amount(XrpCurrencyAmount.ofDrops(1000))
- .signingPublicKey(wallet2.publicKey())
+ .signingPublicKey(keypair2.publicKey())
.build();
SingleSignedTransaction signedOffer2 = signatureService.sign(
- wallet2.privateKey(),
+ keypair2.privateKey(),
nfTokenCreateOffer
);
SubmitResult nfTokenCreateOfferSubmitResult = xrplClient.submit(signedOffer2);
@@ -769,11 +724,11 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
logger.info("NFT Create Offer (Buy) transaction was validated successfully.");
this.scanForResult(
- () -> this.getValidatedAccountObjects(wallet2.publicKey().deriveAddress()),
+ () -> this.getValidatedAccountObjects(keypair2.publicKey().deriveAddress()),
objectsResult -> objectsResult.accountObjects().stream()
.anyMatch(object ->
NfTokenOfferObject.class.isAssignableFrom(object.getClass()) &&
- ((NfTokenOfferObject) object).owner().equals(wallet2.publicKey().deriveAddress())
+ ((NfTokenOfferObject) object).owner().equals(keypair2.publicKey().deriveAddress())
)
);
logger.info("NFTokenOffer object was found in account's objects.");
@@ -814,17 +769,64 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
)
);
- this.scanForResult(
+ scanForNfToken(keypair2, uri);
+ logger.info("NFT was transferred successfully.");
+ }
+
+ private void assertEntryEqualsObjectFromAccountObjects(Address owner, NfTokenObject nfToken)
+ throws JsonRpcClientErrorException {
+ Optional maybeNfTokenPage = xrplClient.accountObjects(
+ AccountObjectsRequestParams.of(owner)
+ ).accountObjects().stream()
+ .filter(object -> NfTokenPageObject.class.isAssignableFrom(object.getClass()))
+ .map(object -> (NfTokenPageObject) object)
+ .findFirst();
+
+ assertThat(maybeNfTokenPage).isNotEmpty();
+ NfTokenPageObject nfTokenPageObject = maybeNfTokenPage.get();
+ assertThat(nfTokenPageObject.nfTokens()).contains(
+ NfTokenWrapper.of(
+ NfToken.builder()
+ .nfTokenId(nfToken.nfTokenId())
+ .uri(nfToken.uri())
+ .build()
+ )
+ );
+
+ LedgerEntryResult entry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.nftPage(nfTokenPageObject.index(), LedgerSpecifier.CURRENT)
+ );
+
+ assertThat(entry.node()).isEqualTo(nfTokenPageObject);
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(nfTokenPageObject.index(), NfTokenPageObject.class, LedgerSpecifier.CURRENT)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(nfTokenPageObject.index(), LedgerSpecifier.CURRENT)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
+
+ private NfTokenObject scanForNfToken(KeyPair minterKeyPair, NfTokenUri uri) {
+ return this.scanForResult(
() -> {
try {
- return xrplClient.accountNfts(wallet2.publicKey().deriveAddress());
+ return xrplClient.accountNfts(minterKeyPair.publicKey().deriveAddress());
} catch (JsonRpcClientErrorException e) {
+ logger.error("Exception occurred while getting account nfts: {}", e.getMessage(), e);
throw new RuntimeException(e);
}
},
result -> result.accountNfts().stream()
.anyMatch(nft -> nft.uri().get().equals(uri))
- );
- logger.info("NFT was transferred successfully.");
+ ).accountNfts()
+ .stream().filter(nft -> nft.uri().get().equals(uri))
+ .findFirst()
+ .get();
}
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/OfferIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/OfferIT.java
index 6b54508a8..7cc13c93c 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/OfferIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/OfferIT.java
@@ -36,12 +36,17 @@
import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
+import org.xrpl.xrpl4j.model.client.ledger.OfferLedgerEntryParams;
import org.xrpl.xrpl4j.model.client.path.BookOffersRequestParams;
import org.xrpl.xrpl4j.model.client.path.BookOffersResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
import org.xrpl.xrpl4j.model.flags.OfferCreateFlags;
import org.xrpl.xrpl4j.model.flags.OfferFlags;
+import org.xrpl.xrpl4j.model.ledger.EscrowObject;
import org.xrpl.xrpl4j.model.ledger.Issue;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.ledger.OfferObject;
import org.xrpl.xrpl4j.model.ledger.RippleStateObject;
import org.xrpl.xrpl4j.model.transactions.Address;
@@ -197,45 +202,9 @@ public void createOpenOfferAndCancel() throws JsonRpcClientErrorException, JsonP
assertThat(offerObject.takerGets()).isEqualTo(offerCreate.takerGets());
assertThat(offerObject.takerPays()).isEqualTo(offerCreate.takerPays());
- cancelOffer(purchaser, offerObject.sequence(), "tesSUCCESS");
- }
-
- /**
- * Cancels an offer and verifies the offer no longer exists on ledger for the account.
- *
- * @param purchaser The {@link KeyPair} of the buyer.
- * @param offerSequence The sequence of the offer.
- *
- * @throws JsonRpcClientErrorException If anything goes wrong while communicating with rippled.
- */
- private void cancelOffer(
- KeyPair purchaser,
- UnsignedInteger offerSequence,
- String expectedResult
- ) throws JsonRpcClientErrorException, JsonProcessingException {
- AccountInfoResult infoResult = this.scanForResult(
- () -> this.getValidatedAccountInfo(purchaser.publicKey().deriveAddress()));
- UnsignedInteger nextSequence = infoResult.accountData().sequence();
-
- FeeResult feeResult = xrplClient.fee();
-
- OfferCancel offerCancel = OfferCancel.builder()
- .account(purchaser.publicKey().deriveAddress())
- .fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())
- .sequence(nextSequence)
- .offerSequence(offerSequence)
- .signingPublicKey(purchaser.publicKey())
- .build();
-
- SingleSignedTransaction signedOfferCancel = signatureService.sign(
- purchaser.privateKey(), offerCancel
- );
- SubmitResult cancelResponse = xrplClient.submit(signedOfferCancel);
- assertThat(cancelResponse.engineResult()).isEqualTo(expectedResult);
+ assertThatEntryEqualsObjectFromAccountObjects(offerObject);
- assertEmptyResults(() -> this.getValidatedAccountObjects(purchaser.publicKey().deriveAddress(), OfferObject.class));
- assertEmptyResults(
- () -> this.getValidatedAccountObjects(purchaser.publicKey().deriveAddress(), RippleStateObject.class));
+ cancelOffer(purchaser, offerObject.sequence(), "tesSUCCESS");
}
@Test
@@ -289,17 +258,6 @@ public void createUnmatchedKillOrFill() throws JsonRpcClientErrorException, Json
() -> this.getValidatedAccountObjects(purchaser.publicKey().deriveAddress(), RippleStateObject.class));
}
- /**
- * Asserts the supplier returns empty results, waiting up to 10 seconds for that condition to be true.
- *
- * @param supplier results supplier.
- */
- private void assertEmptyResults(Supplier> supplier) {
- Awaitility.await()
- .atMost(Durations.TEN_SECONDS)
- .until(supplier::get, Matchers.empty());
- }
-
@Test
public void createFullyMatchedOffer() throws JsonRpcClientErrorException, JsonProcessingException {
// GIVEN a buy offer that has a really great exchange rate
@@ -404,4 +362,77 @@ public RippleStateObject scanForIssuedCurrency(KeyPair purchaser, String currenc
.orElse(null));
}
+
+ private void assertThatEntryEqualsObjectFromAccountObjects(OfferObject offerObject)
+ throws JsonRpcClientErrorException {
+ LedgerEntryResult entry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.offer(
+ OfferLedgerEntryParams.builder()
+ .account(offerObject.account())
+ .seq(offerObject.sequence())
+ .build(),
+ LedgerSpecifier.VALIDATED
+ )
+ );
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(offerObject.index(), OfferObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(offerObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
+
+ /**
+ * Asserts the supplier returns empty results, waiting up to 10 seconds for that condition to be true.
+ *
+ * @param supplier results supplier.
+ */
+ private void assertEmptyResults(Supplier> supplier) {
+ Awaitility.await()
+ .atMost(Durations.TEN_SECONDS)
+ .until(supplier::get, Matchers.empty());
+ }
+
+ /**
+ * Cancels an offer and verifies the offer no longer exists on ledger for the account.
+ *
+ * @param purchaser The {@link KeyPair} of the buyer.
+ * @param offerSequence The sequence of the offer.
+ *
+ * @throws JsonRpcClientErrorException If anything goes wrong while communicating with rippled.
+ */
+ private void cancelOffer(
+ KeyPair purchaser,
+ UnsignedInteger offerSequence,
+ String expectedResult
+ ) throws JsonRpcClientErrorException, JsonProcessingException {
+ AccountInfoResult infoResult = this.scanForResult(
+ () -> this.getValidatedAccountInfo(purchaser.publicKey().deriveAddress()));
+ UnsignedInteger nextSequence = infoResult.accountData().sequence();
+
+ FeeResult feeResult = xrplClient.fee();
+
+ OfferCancel offerCancel = OfferCancel.builder()
+ .account(purchaser.publicKey().deriveAddress())
+ .fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())
+ .sequence(nextSequence)
+ .offerSequence(offerSequence)
+ .signingPublicKey(purchaser.publicKey())
+ .build();
+
+ SingleSignedTransaction signedOfferCancel = signatureService.sign(
+ purchaser.privateKey(), offerCancel
+ );
+ SubmitResult cancelResponse = xrplClient.submit(signedOfferCancel);
+ assertThat(cancelResponse.engineResult()).isEqualTo(expectedResult);
+
+ assertEmptyResults(() -> this.getValidatedAccountObjects(purchaser.publicKey().deriveAddress(), OfferObject.class));
+ assertEmptyResults(
+ () -> this.getValidatedAccountObjects(purchaser.publicKey().deriveAddress(), RippleStateObject.class));
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/PaymentChannelIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/PaymentChannelIT.java
index 3e3fb0994..6ddfc914a 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/PaymentChannelIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/PaymentChannelIT.java
@@ -25,6 +25,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLong;
+import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
@@ -40,7 +41,12 @@
import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
+import org.xrpl.xrpl4j.model.client.ledger.OfferLedgerEntryParams;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
+import org.xrpl.xrpl4j.model.ledger.OfferObject;
import org.xrpl.xrpl4j.model.ledger.PayChannelObject;
import org.xrpl.xrpl4j.model.transactions.PaymentChannelClaim;
import org.xrpl.xrpl4j.model.transactions.PaymentChannelCreate;
@@ -114,14 +120,8 @@ public void createPaymentChannel() throws JsonRpcClientErrorException, JsonProce
//////////////////////////
// Also validate that the channel exists in the account's objects
- scanForResult(
- () -> getValidatedAccountObjects(sourceKeyPair.publicKey().deriveAddress()),
- objectsResult -> objectsResult.accountObjects().stream()
- .anyMatch(object ->
- PayChannelObject.class.isAssignableFrom(object.getClass()) &&
- ((PayChannelObject) object).destination().equals(destinationKeyPair.publicKey().deriveAddress())
- )
- );
+ PayChannelObject payChannelObject = scanForPayChannelObject(sourceKeyPair, destinationKeyPair);
+ assertThatEntryEqualsObjectFromAccountObjects(payChannelObject);
//////////////////////////
// Validate that the amount of the payment channel was deducted from the source
@@ -194,6 +194,9 @@ void createAndClaimPaymentChannel() throws JsonRpcClientErrorException, JsonProc
assertThat(paymentChannel.publicKeyHex()).isNotEmpty().get().isEqualTo(paymentChannelCreate.publicKey());
assertThat(paymentChannel.cancelAfter()).isNotEmpty().get().isEqualTo(paymentChannelCreate.cancelAfter().get());
+ PayChannelObject payChannelObject = scanForPayChannelObject(sourceKeyPair, destinationKeyPair);
+ assertThatEntryEqualsObjectFromAccountObjects(payChannelObject);
+
AccountInfoResult destinationAccountInfo = scanForResult(
() -> getValidatedAccountInfo(destinationKeyPair.publicKey().deriveAddress())
);
@@ -253,6 +256,9 @@ void createAndClaimPaymentChannel() throws JsonRpcClientErrorException, JsonProc
.plus(paymentChannelClaim.balance().get())
)
);
+
+ PayChannelObject payChannelObjectAfterClaim = scanForPayChannelObject(sourceKeyPair, destinationKeyPair);
+ assertThatEntryEqualsObjectFromAccountObjects(payChannelObjectAfterClaim);
}
@Test
@@ -312,6 +318,9 @@ void createAddFundsAndSetExpirationToPaymentChannel() throws JsonRpcClientErrorE
assertThat(paymentChannel.publicKeyHex()).isNotEmpty().get().isEqualTo(paymentChannelCreate.publicKey());
assertThat(paymentChannel.cancelAfter()).isNotEmpty().get().isEqualTo(paymentChannelCreate.cancelAfter().get());
+ PayChannelObject payChannelObject = scanForPayChannelObject(sourceKeyPair, destinationKeyPair);
+ assertThatEntryEqualsObjectFromAccountObjects(payChannelObject);
+
PaymentChannelFund paymentChannelFund = PaymentChannelFund.builder()
.account(sourceKeyPair.publicKey().deriveAddress())
.fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())
@@ -345,6 +354,9 @@ void createAddFundsAndSetExpirationToPaymentChannel() throws JsonRpcClientErrorE
)
);
+ PayChannelObject payChannelObjectAfterFund = scanForPayChannelObject(sourceKeyPair, destinationKeyPair);
+ assertThatEntryEqualsObjectFromAccountObjects(payChannelObjectAfterFund);
+
//////////////////////////
// Then set a new expiry on the channel by submitting a PaymentChannelFund
// transaction with an expiration and 1 drop of XRP in the amount field
@@ -386,6 +398,9 @@ void createAddFundsAndSetExpirationToPaymentChannel() throws JsonRpcClientErrorE
channel.expiration().get().equals(newExpiry)
)
);
+
+ PayChannelObject payChannelObjectAfterExpiryBump = scanForPayChannelObject(sourceKeyPair, destinationKeyPair);
+ assertThatEntryEqualsObjectFromAccountObjects(payChannelObjectAfterExpiryBump);
}
@Test
@@ -449,4 +464,41 @@ void testCurrentAccountChannels() throws JsonRpcClientErrorException, JsonProces
assertThat(accountChannelsResult.ledgerIndex()).isEmpty();
assertThat(accountChannelsResult.ledgerCurrentIndex()).isNotEmpty();
}
+
+ private PayChannelObject scanForPayChannelObject(KeyPair sourceKeyPair, KeyPair destinationKeyPair) {
+ return (PayChannelObject) scanForResult(
+ () -> getValidatedAccountObjects(sourceKeyPair.publicKey().deriveAddress()),
+ objectsResult -> objectsResult.accountObjects().stream()
+ .anyMatch(object ->
+ PayChannelObject.class.isAssignableFrom(object.getClass()) &&
+ ((PayChannelObject) object).destination().equals(destinationKeyPair.publicKey().deriveAddress())
+ )
+ ).accountObjects().stream()
+ .filter(object -> PayChannelObject.class.isAssignableFrom(object.getClass()) &&
+ ((PayChannelObject) object).destination().equals(destinationKeyPair.publicKey().deriveAddress()))
+ .findFirst()
+ .get();
+ }
+
+ private void assertThatEntryEqualsObjectFromAccountObjects(PayChannelObject payChannelObject)
+ throws JsonRpcClientErrorException {
+ LedgerEntryResult entry = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.paymentChannel(
+ payChannelObject.index(),
+ LedgerSpecifier.VALIDATED
+ )
+ );
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(payChannelObject.index(), PayChannelObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entry.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(payChannelObject.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SetRegularKeyIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SetRegularKeyIT.java
index 218335ff9..d96f1140e 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SetRegularKeyIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SetRegularKeyIT.java
@@ -30,9 +30,14 @@
import org.xrpl.xrpl4j.crypto.keys.Seed;
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
+import org.xrpl.xrpl4j.model.ledger.AccountRootObject;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
import org.xrpl.xrpl4j.model.transactions.SetRegularKey;
@@ -50,6 +55,7 @@ void setRegularKeyOnAccount() throws JsonRpcClientErrorException, JsonProcessing
//////////////////////////
// Wait for the account to show up on ledger
AccountInfoResult accountInfo = scanForResult(() -> getValidatedAccountInfo(wallet.publicKey().deriveAddress()));
+ assertEntryEqualsAccountInfo(wallet, accountInfo);
//////////////////////////
// Generate a new wallet locally
@@ -100,6 +106,10 @@ void setRegularKeyOnAccount() throws JsonRpcClientErrorException, JsonProcessing
}
);
+ AccountInfoResult accountInfoAfterRegKeySet = scanForResult(
+ () -> getValidatedAccountInfo(wallet.publicKey().deriveAddress())
+ );
+ assertEntryEqualsAccountInfo(wallet, accountInfoAfterRegKeySet);
}
@Test
@@ -111,6 +121,7 @@ void removeRegularKeyFromAccount() throws JsonRpcClientErrorException, JsonProce
//////////////////////////
// Wait for the account to show up on ledger
AccountInfoResult accountInfo = scanForResult(() -> getValidatedAccountInfo(wallet.publicKey().deriveAddress()));
+ assertEntryEqualsAccountInfo(wallet, accountInfo);
//////////////////////////
// Generate a new wallet locally
@@ -162,6 +173,11 @@ void removeRegularKeyFromAccount() throws JsonRpcClientErrorException, JsonProce
}
);
+ AccountInfoResult accountInfoAfterSet = scanForResult(
+ () -> getValidatedAccountInfo(wallet.publicKey().deriveAddress())
+ );
+ assertEntryEqualsAccountInfo(wallet, accountInfoAfterSet);
+
SetRegularKey removeRegularKey = SetRegularKey.builder()
.account(wallet.publicKey().deriveAddress())
.fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())
@@ -178,9 +194,34 @@ void removeRegularKeyFromAccount() throws JsonRpcClientErrorException, JsonProce
removeResult.transactionResult().hash()
);
- scanForResult(
+ AccountInfoResult accountInfoAfterRemoving = scanForResult(
() -> getValidatedAccountInfo(wallet.publicKey().deriveAddress()),
infoResult -> !infoResult.accountData().regularKey().isPresent()
);
+
+ assertEntryEqualsAccountInfo(wallet, accountInfoAfterRemoving);
+ }
+
+ private void assertEntryEqualsAccountInfo(
+ KeyPair keyPair,
+ AccountInfoResult accountInfo
+ ) throws JsonRpcClientErrorException {
+ LedgerEntryResult accountRoot = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.accountRoot(keyPair.publicKey().deriveAddress(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(accountInfo.accountData()).isEqualTo(accountRoot.node());
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(accountRoot.index(), AccountRootObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(accountRoot.node());
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(accountRoot.index(), LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
}
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SignerListSetIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SignerListSetIT.java
index e7dd423e3..36b7d7bea 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SignerListSetIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/SignerListSetIT.java
@@ -31,16 +31,26 @@
import org.xrpl.xrpl4j.crypto.signing.MultiSignedTransaction;
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitMultiSignedResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
+import org.xrpl.xrpl4j.model.client.transactions.TransactionResult;
+import org.xrpl.xrpl4j.model.ledger.AccountRootObject;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
import org.xrpl.xrpl4j.model.ledger.SignerEntry;
import org.xrpl.xrpl4j.model.ledger.SignerEntryWrapper;
+import org.xrpl.xrpl4j.model.ledger.SignerListObject;
+import org.xrpl.xrpl4j.model.transactions.Hash256;
import org.xrpl.xrpl4j.model.transactions.Payment;
import org.xrpl.xrpl4j.model.transactions.Signer;
import org.xrpl.xrpl4j.model.transactions.SignerListSet;
import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
+import org.xrpl.xrpl4j.model.transactions.metadata.AffectedNode;
+import org.xrpl.xrpl4j.model.transactions.metadata.MetaLedgerEntryType;
import java.util.Collections;
import java.util.Comparator;
@@ -118,6 +128,8 @@ void addSignersToSignerListAndSendPayment() throws JsonRpcClientErrorException,
infoResult -> infoResult.accountData().signerLists().size() == 1
);
+ assertSignerListEntryEqualsAccountInfo(signedSignerListSet.hash(), sourceAccountInfoAfterSignerListSet);
+
assertThat(
sourceAccountInfoAfterSignerListSet.accountData().signerLists().get(0)
.signerEntries().stream()
@@ -226,6 +238,8 @@ void addSignersToSignerListThenDeleteSignerList() throws JsonRpcClientErrorExcep
infoResult -> infoResult.accountData().signerLists().size() == 1
);
+ assertSignerListEntryEqualsAccountInfo(signedSignerListSet.hash(), sourceAccountInfoAfterSignerListSet);
+
assertThat(
sourceAccountInfoAfterSignerListSet.accountData().signerLists().get(0)
.signerEntries().stream()
@@ -263,4 +277,30 @@ void addSignersToSignerListThenDeleteSignerList() throws JsonRpcClientErrorExcep
);
}
+
+ private void assertSignerListEntryEqualsAccountInfo(Hash256 signerListSetTx, AccountInfoResult accountInfo)
+ throws JsonRpcClientErrorException {
+
+ TransactionResult signerListSet = this.getValidatedTransaction(signerListSetTx,
+ SignerListSet.class);
+ Hash256 signerListId = signerListSet.metadata().get()
+ .affectedNodes()
+ .stream()
+ .filter(affectedNode -> affectedNode.ledgerEntryType().equals(MetaLedgerEntryType.SIGNER_LIST))
+ .findFirst()
+ .map(AffectedNode::ledgerIndex)
+ .get();
+
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(signerListId, SignerListObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(accountInfo.accountData().signerLists().get(0));
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(signerListId, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/TicketIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/TicketIT.java
index 15fa9e1c8..d4531f336 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/TicketIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/TicketIT.java
@@ -29,12 +29,20 @@
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
+import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
import org.xrpl.xrpl4j.model.client.fees.FeeResult;
import org.xrpl.xrpl4j.model.client.fees.FeeUtils;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams;
+import org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult;
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
+import org.xrpl.xrpl4j.model.ledger.LedgerObject;
+import org.xrpl.xrpl4j.model.ledger.SignerListObject;
import org.xrpl.xrpl4j.model.ledger.TicketObject;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
+import org.xrpl.xrpl4j.model.transactions.Hash256;
import org.xrpl.xrpl4j.model.transactions.TicketCreate;
+import org.xrpl.xrpl4j.model.transactions.metadata.AffectedNode;
+import org.xrpl.xrpl4j.model.transactions.metadata.MetaLedgerEntryType;
import java.util.List;
@@ -71,11 +79,17 @@ void createTicketAndUseSequenceNumber() throws JsonRpcClientErrorException, Json
submitResult.transactionResult().hash()
);
- this.scanForResult(
+ Hash256 ticketId = this.scanForResult(
() -> this.getValidatedTransaction(
submitResult.transactionResult().hash(),
TicketCreate.class)
- );
+ ).metadata().get()
+ .affectedNodes()
+ .stream()
+ .filter(affectedNode -> affectedNode.ledgerEntryType().equals(MetaLedgerEntryType.TICKET))
+ .findFirst()
+ .map(AffectedNode::ledgerIndex)
+ .get();
AccountInfoResult accountInfoAfterTicketCreate = getValidatedAccountInfo(sourceKeyPair.publicKey().deriveAddress());
assertThat(accountInfoAfterTicketCreate.accountData().ticketCount()).isNotEmpty().get()
@@ -87,6 +101,18 @@ void createTicketAndUseSequenceNumber() throws JsonRpcClientErrorException, Json
);
assertThat(tickets).asList().hasSize(1);
+ LedgerEntryResult entryByIndex = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(ticketId, TicketObject.class, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(tickets.get(0));
+
+ LedgerEntryResult entryByIndexUnTyped = xrplClient.ledgerEntry(
+ LedgerEntryRequestParams.index(ticketId, LedgerSpecifier.VALIDATED)
+ );
+
+ assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
+
AccountSet accountSet = AccountSet.builder()
.account(sourceKeyPair.publicKey().deriveAddress())
.fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())