{ /** * Accessor for the public-key corresponding to the supplied key meta-data. This method exists to support - * implementations that hold private-key material internally, yet need a way for external callers to determine the + * implementations that hold private-key material internally yet need a way for external callers to determine the * actual public key for signature verification or other purposes. * * @param privateKeyable A {@link PrivateKeyable} to derive a public key from. @@ -48,8 +48,7 @@ public interface TransactionSigner
{ PublicKey derivePublicKey(P privateKeyable); /** - * Obtain a singly-signed signature for the supplied transaction using {@code privateKeyable} and the single-sign - * mechanism. + * Get a transaction with a single-sig using {@code privateKeyable}. * * @param privateKeyable The {@link P} used to sign {@code transaction}. * @param transaction The {@link Transaction} to sign. @@ -84,7 +83,7 @@ public interface TransactionSigner
{ Signature sign(P privateKeyable, Attestation attestation); /** - * Obtain a signature for a batch transaction using the supplied {@link P}. + * Get a signature for a batch transaction using the supplied {@link P}. * *
Per XLS-0056, BatchSigners sign a specific format: HashPrefix::batch + flags + count + inner tx IDs. * This differs from both single-signing and multi-signing.
@@ -100,23 +99,6 @@ public interface TransactionSigner{ @Beta Signature signInner(P privateKeyable, Batch batchTransaction); - /** - * Obtain a signature for a batch transaction using the supplied {@link P}. - * - *
Per XLS-0056, BatchSigners sign a specific format: HashPrefix::batch + flags + count + inner tx IDs. - * This differs from both single-signing and multi-signing.
- * - *This method will be marked {@link Beta} until the featureBatch amendment is enabled on mainnet. - * Its API is subject to change.
- * - * @param privateKeyable The {@link P} used to sign {@code batchTransaction}. - * @param batchTransaction The {@link Batch} transaction to sign. - * - * @return A {@link Signature} for the batch transaction. - */ - @Beta - SingleSignedTransaction{ */ Signature multiSignInner(P privateKeyable, Batch batchTransaction); - Signature multiSignOuter(P privateKeyable, Batch batchTransaction); - /** * Obtain a signature for the supplied unsigned transaction using the supplied {@link P}. *
@@ -177,16 +157,19 @@ public interface TransactionSigner
{
* @param This deserializer is needed to allow newer versions of Jackson to deserialize ZonedDateTime values that conform
+ * to the xrpld format, which uses `UTC` for all timezone designations. Newer versions of Jackson instead emit `Z`, so
+ * this serializer ensures that Jackson's serialization for ZonedDateTime uses "UTC" instead of "Z". This serializer is needed because newer Jackson versions changed how the `z` pattern outputs `UTC` time zones.
+ * Previous versions of Jackson would output UTC timezones using `UTC`. Newer versions of Jackson instead emit `Z` in
+ * all cases. This serializer ensures that Jackson's serialization for ZonedDateTime uses "UTC" instead of "Z" to match
+ * the format used by xrpld. This method supports variable precision for the fractional seconds part.
+ *
+ * @param rippleDateTimeString The datetime string to parse; must not be null.
+ *
+ * @return A {@link ZonedDateTime} object representing the parsed datetime.
+ *
+ * @throws NullPointerException if the {@code rippleDateTimeString} is null.
+ * @throws DateTimeParseException if the given string cannot be parsed.
+ */
+ protected static ZonedDateTime parseRippledTime(final String rippleDateTimeString) {
+ Objects.requireNonNull(rippleDateTimeString);
+ // Pattern handles 1-9 decimal places flexibly (see Javadoc above)
+ ZonedDateTime parsed = ZonedDateTime.parse(
+ rippleDateTimeString,
+ DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss[.SSSSSSSSS][.SSSSSS] z", Locale.US)
+ );
+ // Ensure consistent UTC zone representation
+ return parsed.withZoneSameInstant(ZoneOffset.UTC);
+ }
+}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/accounts/AccountTransactionsTransactionTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/accounts/AccountTransactionsTransactionTest.java
index 4c417db9c..c3b312f55 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/accounts/AccountTransactionsTransactionTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/accounts/AccountTransactionsTransactionTest.java
@@ -11,9 +11,12 @@
import org.xrpl.xrpl4j.model.transactions.Payment;
import java.time.LocalDateTime;
-import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+/**
+ * Unit tests for {@link AccountTransactionsTransaction}.
+ */
class AccountTransactionsTransactionTest {
@Test
@@ -26,8 +29,8 @@ void testCloseTimeHuman() {
.build();
assertThat(payment.closeDateHuman()).hasValue(
- ZonedDateTime.of(LocalDateTime.of(2021, 2, 9, 19, 1, 0), ZoneId.of("UTC"))
+ ZonedDateTime.of(LocalDateTime.of(2021, 2, 9, 19, 1, 0), ZoneOffset.UTC)
);
}
-}
\ No newline at end of file
+}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/common/TimeUtilsTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/common/TimeUtilsTest.java
index e8c693501..21e593180 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/common/TimeUtilsTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/common/TimeUtilsTest.java
@@ -6,15 +6,18 @@
import org.junit.jupiter.api.Test;
import java.time.LocalDateTime;
-import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+/**
+ * Unit tests for {@link TimeUtils}.
+ */
class TimeUtilsTest {
@Test
void convertXrplTimeToZonedDateTime() {
UnsignedLong xrplTimestamp = UnsignedLong.valueOf(666212460);
ZonedDateTime zonedDateTime = TimeUtils.xrplTimeToZonedDateTime(xrplTimestamp);
- assertThat(zonedDateTime).isEqualTo(ZonedDateTime.of(LocalDateTime.of(2021, 2, 9, 19, 1, 0), ZoneId.of("UTC")));
+ assertThat(zonedDateTime).isEqualTo(ZonedDateTime.of(LocalDateTime.of(2021, 2, 9, 19, 1, 0), ZoneOffset.UTC));
}
-}
\ No newline at end of file
+}
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerResultJsonTests.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerResultJsonTests.java
index 3598f52d7..87d3713e3 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerResultJsonTests.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerResultJsonTests.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.
@@ -31,9 +31,6 @@
import org.xrpl.xrpl4j.model.transactions.Hash256;
import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class LedgerResultJsonTests extends AbstractJsonTest {
@@ -50,9 +47,7 @@ public void testJson() throws JsonProcessingException, JSONException {
LedgerHeader.builder()
.accountHash(Hash256.of("B258A8BB4743FB74CBBD6E9F67E4A56C4432EA09E5805E4CC2DA26F2DBE8F3D1"))
.closeTime(UnsignedLong.valueOf(638329271))
- .closeTimeHuman(ZonedDateTime.parse("2020-Mar-24 01:41:11.000000000 UTC",
- DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss.SSSSSSSSS z", Locale.US))
- .withZoneSameLocal(ZoneId.of("UTC")))
+ .closeTimeHuman(parseRippledTime("2020-Mar-24 01:41:11.000000000 UTC"))
.closeTimeResolution(UnsignedInteger.valueOf(10))
.closed(true)
.ledgerHash(Hash256.of("3652D7FD0576BC452C0D2E9B747BDD733075971D1A9A1D98125055DEF428721A"))
@@ -86,7 +81,6 @@ public void testJson() throws JsonProcessingException, JSONException {
" }";
assertCanSerializeAndDeserialize(result, json);
-
}
@Test
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/serverinfo/LedgerRangeUtilsTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/serverinfo/LedgerRangeUtilsTest.java
index 09552ff49..768b8d914 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/serverinfo/LedgerRangeUtilsTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/serverinfo/LedgerRangeUtilsTest.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.
@@ -46,12 +46,12 @@ public void completeLedgersRanges() {
assertThat(reportingServerInfo.map(
($) -> null,
($) -> null,
- param -> param.completeLedgers()
+ ServerInfo::completeLedgers
).size()).isEqualTo(0);
ServerInfo rippledServerInfo = RippledServerInfoTest.rippledServerInfo("empty");
assertThat(rippledServerInfo.map(
- param -> param.completeLedgers(),
+ ServerInfo::completeLedgers,
($) -> null,
($) -> null
).size()).isEqualTo(0);
@@ -59,35 +59,35 @@ public void completeLedgersRanges() {
serverInfo = ClioServerInfoTest.clioServerInfo("");
assertThat(serverInfo.map(
($) -> null,
- param -> param.completeLedgers(),
+ ServerInfo::completeLedgers,
($) -> null
).size()).isEqualTo(0);
serverInfo = ClioServerInfoTest.clioServerInfo("foo");
assertThat(serverInfo.map(
($) -> null,
- param -> param.completeLedgers(),
+ ServerInfo::completeLedgers,
($) -> null
).size()).isEqualTo(0);
serverInfo = ClioServerInfoTest.clioServerInfo("foo100");
assertThat(serverInfo.map(
($) -> null,
- param -> param.completeLedgers(),
+ ServerInfo::completeLedgers,
($) -> null
).size()).isEqualTo(0);
serverInfo = ClioServerInfoTest.clioServerInfo("1--2");
assertThat(serverInfo.map(
($) -> null,
- param -> param.completeLedgers(),
+ ServerInfo::completeLedgers,
($) -> null
).size()).isEqualTo(0);
serverInfo = ClioServerInfoTest.clioServerInfo("0");
List
+ *
+ *
+ *