From 0f599ff3a2254cef24e87e63efa38240011b6d68 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sun, 20 Oct 2024 10:34:24 -0400 Subject: [PATCH 01/10] add all MPT transactions. Stopped at Clawback changes so I can try out a different approach to MptAmounts --- .../model/flags/MpTokenAuthorizeFlags.java | 76 +++++ .../flags/MpTokenIssuanceCreateFlags.java | 272 ++++++++++++++++++ .../model/flags/MpTokenIssuanceSetFlags.java | 85 ++++++ .../modules/AssetScaleDeserializer.java | 29 ++ .../jackson/modules/AssetScaleSerializer.java | 27 ++ .../MpTokenIssuanceIdDeserializer.java | 46 +++ .../modules/MpTokenIssuanceIdSerializer.java | 46 +++ .../modules/MptMaximumAmountDeserializer.java | 28 ++ .../modules/MptMaximumAmountSerializer.java | 27 ++ .../model/transactions/CurrencyAmount.java | 14 +- .../model/transactions/MpTokenAmount.java | 52 ++++ .../model/transactions/MpTokenAuthorize.java | 38 +++ .../transactions/MpTokenIssuanceCreate.java | 49 ++++ .../transactions/MpTokenIssuanceDestroy.java | 46 +++ .../transactions/MpTokenIssuanceSet.java | 40 +++ .../model/transactions/TransactionType.java | 11 +- .../xrpl4j/model/transactions/Wrappers.java | 54 ++++ 17 files changed, 937 insertions(+), 3 deletions(-) create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleDeserializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleSerializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdDeserializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdSerializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceDestroy.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java new file mode 100644 index 000000000..1d8217139 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java @@ -0,0 +1,76 @@ +package org.xrpl.xrpl4j.model.flags; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: core + * %% + * Copyright (C) 2020 - 2023 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +/** + * A set of static {@link TransactionFlags} which can be set on + * {@link org.xrpl.xrpl4j.model.transactions.MpTokenAuthorize} transactions. + */ +@SuppressWarnings("abbreviationaswordinname") +public class MpTokenAuthorizeFlags extends TransactionFlags { + + /** + * Constant {@link MpTokenAuthorizeFlags} for the {@code tfMPTLock} flag. + */ + public static final MpTokenAuthorizeFlags UNAUTHORIZE = new MpTokenAuthorizeFlags(0x00000001); + + private MpTokenAuthorizeFlags(long value) { + super(value); + } + + private MpTokenAuthorizeFlags() { + } + + /** + * Construct {@link MpTokenAuthorizeFlags} with a given value. + * + * @param value The long-number encoded flags value of this {@link MpTokenAuthorizeFlags}. + * + * @return New {@link MpTokenAuthorizeFlags}. + */ + public static MpTokenAuthorizeFlags of(long value) { + return new MpTokenAuthorizeFlags(value); + } + + /** + * Construct an empty instance of {@link MpTokenAuthorizeFlags}. Transactions with empty flags will not be serialized + * with a {@code Flags} field. + * + * @return An empty {@link MpTokenAuthorizeFlags}. + */ + public static MpTokenAuthorizeFlags empty() { + return new MpTokenAuthorizeFlags(); + } + + /** + * If set and transaction is submitted by a holder, it indicates that the holder no longer wants to hold the MPToken, + * which will be deleted as a result. If the the holder's MPToken has non-zero balance while trying to set this flag, + * the transaction will fail. On the other hand, if set and transaction is submitted by an issuer, it would mean that + * the issuer wants to unauthorize the holder (only applicable for allow-listing), which would unset the + * lsfMPTAuthorized flag on the MPToken. + * + * @return {@code true} if {@code tfMPTUnauthorize} is set, otherwise {@code false}. + */ + public boolean tfMptUnauthorize() { + return this.isSet(UNAUTHORIZE); + } + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java new file mode 100644 index 000000000..b142404f6 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java @@ -0,0 +1,272 @@ +package org.xrpl.xrpl4j.model.flags; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: core + * %% + * Copyright (C) 2020 - 2023 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +/** + * A set of static {@link TransactionFlags} which can be set on + * {@link org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceCreate} transactions. + */ +@SuppressWarnings("abbreviationaswordinname") +public class MpTokenIssuanceCreateFlags extends TransactionFlags { + + /** + * Constant {@link MpTokenIssuanceCreateFlags} for the {@code tfMPTCanLock} flag. + */ + protected static final MpTokenIssuanceCreateFlags CAN_LOCK = new MpTokenIssuanceCreateFlags(0x00000002); + /** + * Constant {@link MpTokenIssuanceCreateFlags} for the {@code tfMPTRequireAuth} flag. + */ + protected static final MpTokenIssuanceCreateFlags REQUIRE_AUTH = new MpTokenIssuanceCreateFlags(0x00000004); + /** + * Constant {@link MpTokenIssuanceCreateFlags} for the {@code tfMPTCanEscrow} flag. + */ + protected static final MpTokenIssuanceCreateFlags CAN_ESCROW = new MpTokenIssuanceCreateFlags(0x00000008); + /** + * Constant {@link MpTokenIssuanceCreateFlags} for the {@code tfMPTCanTrade} flag. + */ + protected static final MpTokenIssuanceCreateFlags CAN_TRADE = new MpTokenIssuanceCreateFlags(0x00000010); + /** + * Constant {@link MpTokenIssuanceCreateFlags} for the {@code tfMPTCanTransfer} flag. + */ + protected static final MpTokenIssuanceCreateFlags CAN_TRANSFER = new MpTokenIssuanceCreateFlags(0x00000020); + /** + * Constant {@link MpTokenIssuanceCreateFlags} for the {@code tfMPTCanClawback} flag. + */ + protected static final MpTokenIssuanceCreateFlags CAN_CLAWBACK = new MpTokenIssuanceCreateFlags(0x00000040); + + + private MpTokenIssuanceCreateFlags(long value) { + super(value); + } + + private MpTokenIssuanceCreateFlags() { + } + + /** + * Create a new {@link Builder}. + * + * @return A new {@link Builder}. + */ + public static Builder builder() { + return new Builder(); + } + + private static MpTokenIssuanceCreateFlags of( + boolean tfFullyCanonicalSig, + boolean tfMPTCanLock, + boolean tfMPTRequireAuth, + boolean tfMPTCanEscrow, + boolean tfMPTCanTrade, + boolean tfMPTCanTransfer, + boolean tfMPTCanClawback + ) { + return new MpTokenIssuanceCreateFlags( + TransactionFlags.of( + tfFullyCanonicalSig ? TransactionFlags.FULLY_CANONICAL_SIG : UNSET, + tfMPTCanLock ? CAN_LOCK : UNSET, + tfMPTRequireAuth ? REQUIRE_AUTH : UNSET, + tfMPTCanEscrow ? CAN_ESCROW : UNSET, + tfMPTCanTransfer ? CAN_TRANSFER : UNSET, + tfMPTCanTrade ? CAN_TRADE : UNSET, + tfMPTCanClawback ? CAN_CLAWBACK : UNSET + ).getValue() + ); + } + + /** + * Construct {@link MpTokenIssuanceCreateFlags} with a given value. + * + * @param value The long-number encoded flags value of this {@link MpTokenIssuanceCreateFlags}. + * + * @return New {@link MpTokenIssuanceCreateFlags}. + */ + public static MpTokenIssuanceCreateFlags of(long value) { + return new MpTokenIssuanceCreateFlags(value); + } + + /** + * Construct an empty instance of {@link MpTokenIssuanceCreateFlags}. Transactions with empty flags will not be + * serialized with a {@code Flags} field. + * + * @return An empty {@link MpTokenIssuanceCreateFlags}. + */ + public static MpTokenIssuanceCreateFlags empty() { + return new MpTokenIssuanceCreateFlags(); + } + + /** + * If set, indicates that the MPT can be locked both individually and globally. If not set, the MPT cannot be locked + * in any way. + * + * @return {@code true} if {@code tfMPTCanLock} is set, otherwise {@code false}. + */ + public boolean tfMptCanLock() { + return this.isSet(CAN_LOCK); + } + + /** + * If set, indicates that individual holders must be authorized. This enables issuers to limit who can hold their + * assets. + * + * @return {@code true} if {@code tfMPTRequireAuth} is set, otherwise {@code false}. + */ + public boolean tfMptRequireAuth() { + return this.isSet(REQUIRE_AUTH); + } + + /** + * If set, indicates that individual holders can place their balances into an escrow. + * + * @return {@code true} if {@code tfMPTCanEscrow} is set, otherwise {@code false}. + */ + public boolean tfMptCanEscrow() { + return this.isSet(CAN_ESCROW); + } + + /** + * If set, indicates that individual holders can trade their balances using the XRP Ledger DEX. + * + * @return {@code true} if {@code tfMPTCanTrade} is set, otherwise {@code false}. + */ + public boolean tfMptCanTrade() { + return this.isSet(CAN_TRADE); + } + + /** + * If set, indicates that tokens may be transferred to other accounts that are not the issuer. + * + * @return {@code true} if {@code tfMPTCanTransfer} is set, otherwise {@code false}. + */ + public boolean tfMptCanTransfer() { + return this.isSet(CAN_TRANSFER); + } + + /** + * If set, indicates that the issuer may use the Clawback transaction to clawback value from individual holders. + * + * @return {@code true} if {@code tfMPTCanClawback} is set, otherwise {@code false}. + */ + public boolean tfMptCanClawback() { + return this.isSet(CAN_CLAWBACK); + } + + /** + * A builder class for {@link MpTokenIssuanceCreateFlags}. + */ + public static class Builder { + + boolean tfMptCanLock = false; + boolean tfMptRequireAuth = false; + boolean tfMptCanEscrow = false; + boolean tfMptCanTrade = false; + boolean tfMptCanTransfer = false; + boolean tfMptCanClawback = false; + + /** + * Set {@code tfMptCanLock} to the given value. + * + * @param tfMptCanLock A boolean value. + * + * @return The same {@link Builder}. + */ + public Builder tfMptCanLock(boolean tfMptCanLock) { + this.tfMptCanLock = tfMptCanLock; + return this; + } + + /** + * Set {@code tfMptRequireAuth} to the given value. + * + * @param tfMptRequireAuth A boolean value. + * + * @return The same {@link Builder}. + */ + public Builder tfMptRequireAuth(boolean tfMptRequireAuth) { + this.tfMptRequireAuth = tfMptRequireAuth; + return this; + } + + /** + * Set {@code tfMptCanEscrow} to the given value. + * + * @param tfMptCanEscrow A boolean value. + * + * @return The same {@link Builder}. + */ + public Builder tfMptCanEscrow(boolean tfMptCanEscrow) { + this.tfMptCanEscrow = tfMptCanEscrow; + return this; + } + + /** + * Set {@code tfMptCanTrade} to the given value. + * + * @param tfMptCanTrade A boolean value. + * + * @return The same {@link Builder}. + */ + public Builder tfMptCanTrade(boolean tfMptCanTrade) { + this.tfMptCanTrade = tfMptCanTrade; + return this; + } + + /** + * Set {@code tfMptCanTransfer} to the given value. + * + * @param tfMptCanTransfer A boolean value. + * + * @return The same {@link Builder}. + */ + public Builder tfMptCanTransfer(boolean tfMptCanTransfer) { + this.tfMptCanTransfer = tfMptCanTransfer; + return this; + } + + /** + * Set {@code tfMptCanClawback} to the given value. + * + * @param tfMptCanClawback A boolean value. + * + * @return The same {@link Builder}. + */ + public Builder tfMptCanClawback(boolean tfMptCanClawback) { + this.tfMptCanClawback = tfMptCanClawback; + return this; + } + + /** + * Build a new {@link MpTokenIssuanceCreateFlags} from the current boolean values. + * + * @return A new {@link MpTokenIssuanceCreateFlags}. + */ + public MpTokenIssuanceCreateFlags build() { + return MpTokenIssuanceCreateFlags.of( + true, + tfMptCanLock, + tfMptRequireAuth, + tfMptCanEscrow, + tfMptCanTrade, + tfMptCanTransfer, + tfMptCanClawback + ); + } + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java new file mode 100644 index 000000000..dcc2f018a --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java @@ -0,0 +1,85 @@ +package org.xrpl.xrpl4j.model.flags; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: core + * %% + * Copyright (C) 2020 - 2023 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +/** + * A set of static {@link TransactionFlags} which can be set on + * {@link org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceSet} transactions. + */ +@SuppressWarnings("abbreviationaswordinname") +public class MpTokenIssuanceSetFlags extends TransactionFlags { + + /** + * Constant {@link MpTokenIssuanceSetFlags} for the {@code tfMPTLock} flag. + */ + public static final MpTokenIssuanceSetFlags LOCK = new MpTokenIssuanceSetFlags(0x00000001); + /** + * Constant {@link MpTokenIssuanceSetFlags} for the {@code tfMPTUnlock} flag. + */ + public static final MpTokenIssuanceSetFlags UNLOCK = new MpTokenIssuanceSetFlags(0x00000002); + + private MpTokenIssuanceSetFlags(long value) { + super(value); + } + + private MpTokenIssuanceSetFlags() { + } + + /** + * Construct {@link MpTokenIssuanceSetFlags} with a given value. + * + * @param value The long-number encoded flags value of this {@link MpTokenIssuanceSetFlags}. + * + * @return New {@link MpTokenIssuanceSetFlags}. + */ + public static MpTokenIssuanceSetFlags of(long value) { + return new MpTokenIssuanceSetFlags(value); + } + + /** + * Construct an empty instance of {@link MpTokenIssuanceSetFlags}. Transactions with empty flags will not be + * serialized with a {@code Flags} field. + * + * @return An empty {@link MpTokenIssuanceSetFlags}. + */ + public static MpTokenIssuanceSetFlags empty() { + return new MpTokenIssuanceSetFlags(); + } + + /** + * If set, indicates that all MPT balances for this asset should be locked. + * + * @return {@code true} if {@code tfMPTLock} is set, otherwise {@code false}. + */ + public boolean tfMptLock() { + return this.isSet(LOCK); + } + + /** + * If set, indicates that all MPT balances for this asset should be unlocked. + * + * @return {@code true} if {@code tfMPTUnlock} is set, otherwise {@code false}. + */ + public boolean tfMptUnlock() { + return this.isSet(UNLOCK); + } + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleDeserializer.java new file mode 100644 index 000000000..2d976a4f0 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleDeserializer.java @@ -0,0 +1,29 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.google.common.primitives.UnsignedInteger; +import com.google.common.primitives.UnsignedLong; +import org.xrpl.xrpl4j.model.transactions.AssetPrice; +import org.xrpl.xrpl4j.model.transactions.AssetScale; + +import java.io.IOException; + +/** + * Custom Jackson deserializer for {@link AssetPrice}s. + */ +public class AssetScaleDeserializer extends StdDeserializer { + + /** + * No-args constructor. + */ + public AssetScaleDeserializer() { + super(AssetScale.class); + } + + @Override + public AssetScale deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { + return AssetScale.of(UnsignedInteger.valueOf(jsonParser.getLongValue())); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleSerializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleSerializer.java new file mode 100644 index 000000000..792b77c51 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/AssetScaleSerializer.java @@ -0,0 +1,27 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; +import org.xrpl.xrpl4j.model.transactions.AssetPrice; +import org.xrpl.xrpl4j.model.transactions.AssetScale; + +import java.io.IOException; + +/** + * Custom Jackson serializer for {@link AssetPrice}s. + */ +public class AssetScaleSerializer extends StdScalarSerializer { + + /** + * No-args constructor. + */ + public AssetScaleSerializer() { + super(AssetScale.class, false); + } + + @Override + public void serialize(AssetScale value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeNumber(value.value().longValue()); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdDeserializer.java new file mode 100644 index 000000000..29dca8a41 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdDeserializer.java @@ -0,0 +1,46 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: model + * %% + * Copyright (C) 2020 - 2022 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; + +import java.io.IOException; + +/** + * Custom Jackson deserializer for {@link MpTokenIssuanceId}s. + */ +public class MpTokenIssuanceIdDeserializer extends StdDeserializer { + + /** + * No-args constructor. + */ + public MpTokenIssuanceIdDeserializer() { + super(MpTokenIssuanceId.class); + } + + @Override + public MpTokenIssuanceId deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { + return MpTokenIssuanceId.of(jsonParser.getText()); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdSerializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdSerializer.java new file mode 100644 index 000000000..a16a6a1cf --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenIssuanceIdSerializer.java @@ -0,0 +1,46 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: model + * %% + * Copyright (C) 2020 - 2022 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; + +import java.io.IOException; + +/** + * Custom Jackson serializer for {@link MpTokenIssuanceId}s. + */ +public class MpTokenIssuanceIdSerializer extends StdScalarSerializer { + + /** + * No-args constructor. + */ + public MpTokenIssuanceIdSerializer() { + super(MpTokenIssuanceId.class, false); + } + + @Override + public void serialize(MpTokenIssuanceId value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeString(value.value()); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java new file mode 100644 index 000000000..9cf7963f7 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java @@ -0,0 +1,28 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.google.common.primitives.UnsignedLong; +import org.xrpl.xrpl4j.model.transactions.MptMaximumAmount; + +import java.io.IOException; + +/** + * Custom Jackson deserializer for {@link MptMaximumAmount}s. + */ +public class MptMaximumAmountDeserializer extends StdDeserializer { + + /** + * No-args constructor. + */ + public MptMaximumAmountDeserializer() { + super(MptMaximumAmount.class); + } + + @Override + public MptMaximumAmount deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { + // sfMaximumAmount is an STUInt64s, which in JSON is represented as a hex-encoded String. + return MptMaximumAmount.of(UnsignedLong.valueOf(jsonParser.getText(), 16)); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java new file mode 100644 index 000000000..f1efdc208 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java @@ -0,0 +1,27 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; +import org.xrpl.xrpl4j.model.transactions.MptMaximumAmount; + +import java.io.IOException; + +/** + * Custom Jackson serializer for {@link MptMaximumAmount}s. + */ +public class MptMaximumAmountSerializer extends StdScalarSerializer { + + /** + * No-args constructor. + */ + public MptMaximumAmountSerializer() { + super(MptMaximumAmount.class, false); + } + + @Override + public void serialize(MptMaximumAmount count, JsonGenerator gen, SerializerProvider provider) throws IOException { + // sfMaximumAmount is an STUInt64s, which in JSON is represented as a hex-encoded String. + gen.writeString(count.value().toString(16)); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmount.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmount.java index bb088f5ab..76a83af63 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmount.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmount.java @@ -51,18 +51,24 @@ public interface CurrencyAmount { * {@link XrpCurrencyAmount}. * @param issuedCurrencyAmountConsumer A {@link Consumer} that is called if this instance is of type * {@link IssuedCurrencyAmount}. + * @param mpTokenAmountConsumer A {@link Consumer} that is called if this instance is of type + * {@link MpTokenAmount}. */ default void handle( final Consumer xrpCurrencyAmountHandler, - final Consumer issuedCurrencyAmountConsumer + final Consumer issuedCurrencyAmountConsumer, + final Consumer mpTokenAmountConsumer ) { Objects.requireNonNull(xrpCurrencyAmountHandler); Objects.requireNonNull(issuedCurrencyAmountConsumer); + Objects.requireNonNull(mpTokenAmountConsumer); if (XrpCurrencyAmount.class.isAssignableFrom(this.getClass())) { xrpCurrencyAmountHandler.accept((XrpCurrencyAmount) this); } else if (IssuedCurrencyAmount.class.isAssignableFrom(this.getClass())) { issuedCurrencyAmountConsumer.accept((IssuedCurrencyAmount) this); + } else if (MpTokenAmount.class.isAssignableFrom(this.getClass())) { + mpTokenAmountConsumer.accept((MpTokenAmount) this); } else { throw new IllegalStateException(String.format("Unsupported CurrencyAmount Type: %s", this.getClass())); } @@ -81,15 +87,19 @@ default void handle( */ default R map( final Function xrpCurrencyAmountMapper, - final Function issuedCurrencyAmountMapper + final Function issuedCurrencyAmountMapper, + final Function mpTokenAmountMapper ) { Objects.requireNonNull(xrpCurrencyAmountMapper); Objects.requireNonNull(issuedCurrencyAmountMapper); + Objects.requireNonNull(mpTokenAmountMapper); if (XrpCurrencyAmount.class.isAssignableFrom(this.getClass())) { return xrpCurrencyAmountMapper.apply((XrpCurrencyAmount) this); } else if (IssuedCurrencyAmount.class.isAssignableFrom(this.getClass())) { return issuedCurrencyAmountMapper.apply((IssuedCurrencyAmount) this); + } else if (MpTokenAmount.class.isAssignableFrom(this.getClass())) { + return mpTokenAmountMapper.apply((MpTokenAmount) this); } else { throw new IllegalStateException(String.format("Unsupported CurrencyAmount Type: %s", this.getClass())); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java new file mode 100644 index 000000000..47937e1d3 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java @@ -0,0 +1,52 @@ +package org.xrpl.xrpl4j.model.transactions; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedLong; +import org.immutables.value.Value; +import org.immutables.value.Value.Auxiliary; +import org.immutables.value.Value.Derived; +import org.immutables.value.Value.Immutable; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenAmount.class) +@JsonDeserialize(as = ImmutableMpTokenAmount.class) +public interface MpTokenAmount extends CurrencyAmount { + + /** + * Construct a {@code MpTokenAmount} builder. + * + * @return An {@link ImmutableMpTokenAmount.Builder}. + */ + static ImmutableMpTokenAmount.Builder builder() { + return ImmutableMpTokenAmount.builder(); + } + + @JsonProperty("mpt_issuance_id") + MpTokenIssuanceId mptIssuanceId(); + + String value(); + + @Value.Derived + @JsonIgnore + default UnsignedLong unsignedLongValue() { + return isNegative() ? + UnsignedLong.valueOf(value().substring(1)) : + UnsignedLong.valueOf(value()); + } + + /** + * Indicates whether this amount is positive or negative. + * + * @return {@code true} if this amount is negative; {@code false} otherwise (i.e., if the value is 0 or positive). + */ + @Derived + @JsonIgnore // <-- This is not actually part of the binary serialization format, so exclude from JSON + @Auxiliary + default boolean isNegative() { + return value().startsWith("-"); + } + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java new file mode 100644 index 000000000..edd8fc6ca --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java @@ -0,0 +1,38 @@ +package org.xrpl.xrpl4j.model.transactions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceSetFlags; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenAuthorize.class) +@JsonDeserialize(as = ImmutableMpTokenAuthorize.class) +public interface MpTokenAuthorize extends Transaction { + + /** + * Construct a {@code MpTokenAuthorize} builder. + * + * @return An {@link ImmutableMpTokenAuthorize.Builder}. + */ + static ImmutableMpTokenAuthorize.Builder builder() { + return ImmutableMpTokenAuthorize.builder(); + } + + @JsonProperty("Flags") + @Value.Default + default MpTokenAuthorizeFlags flags() { + return MpTokenAuthorizeFlags.empty(); + } + + @JsonProperty("MPTokenIssuanceID") + MpTokenIssuanceId mpTokenIssuanceId(); + + @JsonProperty("MPTokenHolder") + Optional
mpTokenHolder(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java new file mode 100644 index 000000000..189ed54cd --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java @@ -0,0 +1,49 @@ +package org.xrpl.xrpl4j.model.transactions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceCreateFlags; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenIssuanceCreate.class) +@JsonDeserialize(as = ImmutableMpTokenIssuanceCreate.class) +public interface MpTokenIssuanceCreate extends Transaction { + + /** + * Construct a {@code MpTokenIssuanceCreate} builder. + * + * @return An {@link ImmutableMpTokenIssuanceCreate.Builder}. + */ + static ImmutableMpTokenIssuanceCreate.Builder builder() { + return ImmutableMpTokenIssuanceCreate.builder(); + } + + @JsonProperty("AssetScale") + Optional assetScale(); + + /** + * Set of {@link MpTokenIssuanceCreateFlags}s for this {@link MpTokenIssuanceCreate}. + * + * @return The {@link MpTokenIssuanceCreateFlags} for this transaction. + */ + @JsonProperty("Flags") + @Value.Default + default MpTokenIssuanceCreateFlags flags() { + return MpTokenIssuanceCreateFlags.empty(); + } + + @JsonProperty("TransferFee") + Optional transferFee(); + + @JsonProperty("MaximumAmount") + Optional maximumAmount(); + + @JsonProperty("MPTokenMetadata") + Optional mpTokenMetadata(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceDestroy.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceDestroy.java new file mode 100644 index 000000000..b55034b69 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceDestroy.java @@ -0,0 +1,46 @@ +package org.xrpl.xrpl4j.model.transactions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceCreateFlags; +import org.xrpl.xrpl4j.model.flags.TransactionFlags; +import org.xrpl.xrpl4j.model.transactions.ImmutableMpTokenIssuanceDestroy.Builder; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenIssuanceDestroy.class) +@JsonDeserialize(as = ImmutableMpTokenIssuanceDestroy.class) +public interface MpTokenIssuanceDestroy extends Transaction { + + /** + * Construct a {@code MpTokenIssuanceDestroy} builder. + * + * @return An {@link Builder}. + */ + static Builder builder() { + return ImmutableMpTokenIssuanceDestroy.builder(); + } + + /** + * Set of {@link TransactionFlags}s for this {@link MpTokenIssuanceDestroy}, which only allows the + * {@code tfFullyCanonicalSig} flag, which is deprecated. + * + *

The value of the flags cannot be set manually, but exists for JSON serialization/deserialization only and for + * proper signature computation in rippled. + * + * @return Always {@link TransactionFlags#EMPTY}. + */ + @JsonProperty("Flags") + @Value.Default + default TransactionFlags flags() { + return TransactionFlags.EMPTY; + } + + @JsonProperty("MPTokenIssuanceID") + MpTokenIssuanceId mpTokenIssuanceId(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java new file mode 100644 index 000000000..ec823cab7 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java @@ -0,0 +1,40 @@ +package org.xrpl.xrpl4j.model.transactions; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceSetFlags; +import org.xrpl.xrpl4j.model.flags.TransactionFlags; +import org.xrpl.xrpl4j.model.transactions.ImmutableMpTokenIssuanceDestroy.Builder; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenIssuanceSet.class) +@JsonDeserialize(as = ImmutableMpTokenIssuanceSet.class) +public interface MpTokenIssuanceSet extends Transaction { + + /** + * Construct a {@code MpTokenIssuanceSet} builder. + * + * @return An {@link ImmutableMpTokenIssuanceSet.Builder}. + */ + static ImmutableMpTokenIssuanceSet.Builder builder() { + return ImmutableMpTokenIssuanceSet.builder(); + } + + @JsonProperty("Flags") + @Value.Default + default MpTokenIssuanceSetFlags flags() { + return MpTokenIssuanceSetFlags.empty(); + } + + @JsonProperty("MPTokenIssuanceID") + MpTokenIssuanceId mpTokenIssuanceId(); + + @JsonProperty("MPTokenHolder") + Optional

mpTokenHolder(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionType.java index bc19f8dbf..dece23757 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionType.java @@ -336,7 +336,16 @@ public enum TransactionType { * is subject to change.

*/ @Beta - ORACLE_DELETE("OracleDelete"); + ORACLE_DELETE("OracleDelete"), + + @Beta + MPT_ISSUANCE_CREATE("MPTokenIssuanceCreate"), + @Beta + MPT_ISSUANCE_DESTROY("MPTokenIssuanceDestroy"), + @Beta + MPT_ISSUANCE_SET("MPTokenIssuanceSet"), + @Beta + MPT_AUTHORIZE("MPTokenAuthorize"); private final String value; diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java index 7e036c2cf..cbc89b8ac 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java @@ -39,6 +39,8 @@ import org.xrpl.xrpl4j.model.jackson.modules.AddressSerializer; import org.xrpl.xrpl4j.model.jackson.modules.AssetPriceDeserializer; import org.xrpl.xrpl4j.model.jackson.modules.AssetPriceSerializer; +import org.xrpl.xrpl4j.model.jackson.modules.AssetScaleDeserializer; +import org.xrpl.xrpl4j.model.jackson.modules.AssetScaleSerializer; import org.xrpl.xrpl4j.model.jackson.modules.DidDataDeserializer; import org.xrpl.xrpl4j.model.jackson.modules.DidDataSerializer; import org.xrpl.xrpl4j.model.jackson.modules.DidDocumentDeserializer; @@ -49,6 +51,10 @@ import org.xrpl.xrpl4j.model.jackson.modules.Hash256Serializer; import org.xrpl.xrpl4j.model.jackson.modules.MarkerDeserializer; import org.xrpl.xrpl4j.model.jackson.modules.MarkerSerializer; +import org.xrpl.xrpl4j.model.jackson.modules.MpTokenIssuanceIdDeserializer; +import org.xrpl.xrpl4j.model.jackson.modules.MpTokenIssuanceIdSerializer; +import org.xrpl.xrpl4j.model.jackson.modules.MptMaximumAmountDeserializer; +import org.xrpl.xrpl4j.model.jackson.modules.MptMaximumAmountSerializer; import org.xrpl.xrpl4j.model.jackson.modules.NetworkIdDeserializer; import org.xrpl.xrpl4j.model.jackson.modules.NetworkIdSerializer; import org.xrpl.xrpl4j.model.jackson.modules.NfTokenIdDeserializer; @@ -776,4 +782,52 @@ public String toString() { } } + + @Value.Immutable + @Wrapped + @JsonSerialize(as = AssetScale.class, using = AssetScaleSerializer.class) + @JsonDeserialize(as = AssetScale.class, using = AssetScaleDeserializer.class) + @Beta + abstract static class _AssetScale extends Wrapper implements Serializable { + + @Override + public String toString() { + return this.value().toString(); + } + + } + + @Value.Immutable + @Wrapped + @JsonSerialize(as = MptMaximumAmount.class, using = MptMaximumAmountSerializer.class) + @JsonDeserialize(as = MptMaximumAmount.class, using = MptMaximumAmountDeserializer.class) + @Beta + abstract static class _MptMaximumAmount extends Wrapper implements Serializable { + + public static MptMaximumAmount of(long amount) { + return MptMaximumAmount.of(UnsignedLong.valueOf(amount)); + } + + @Override + public String toString() { + return this.value().toString(); + } + + } + + @Value.Immutable + @Wrapped + @JsonSerialize(as = MpTokenIssuanceId.class, using = MpTokenIssuanceIdSerializer.class) + @JsonDeserialize(as = MpTokenIssuanceId.class, using = MpTokenIssuanceIdDeserializer.class) + @Beta + abstract static class _MpTokenIssuanceId extends Wrapper implements Serializable { + + // TODO: Do clients ever need to construct an issuance id given a sequence and issuer AccountID? + + @Override + public String toString() { + return this.value(); + } + + } } From 565d6f9f48f07bdf942a3144ca3add975e72b0fd Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sun, 20 Oct 2024 10:55:23 -0400 Subject: [PATCH 02/10] add mptokenholder to clawback --- .../xrpl4j/model/transactions/Clawback.java | 6 +- .../model/transactions/MpTokenAuthorize.java | 1 + .../transactions/CurrencyAmountTest.java | 78 ++++++++----------- .../NegativeTransactionMetadataTest.java | 11 ++- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java index 8c5c3bdcf..8c5833d63 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java @@ -8,6 +8,8 @@ import org.immutables.value.Value.Immutable; import org.xrpl.xrpl4j.model.flags.TransactionFlags; +import java.util.Optional; + /** * Clawback an issued currency that exists on a Trustline. * @@ -49,7 +51,9 @@ default TransactionFlags flags() { * @return An {@link IssuedCurrencyAmount} indicating the amount to clawback. */ @JsonProperty("Amount") - IssuedCurrencyAmount amount(); + CurrencyAmount amount(); + @JsonProperty("MPTokenHolder") + Optional
mpTokenHolder(); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java index edd8fc6ca..6ae9018fb 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.immutables.value.Value; import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenAuthorizeFlags; import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceSetFlags; import java.util.Optional; diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmountTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmountTest.java index 935019d7d..172a9bbe4 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmountTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/CurrencyAmountTest.java @@ -61,28 +61,42 @@ public boolean isNegative() { } @Test - public void handleXrp() { - XrpCurrencyAmount xrpCurrencyAmount = XrpCurrencyAmount.ofDrops(0L); - - xrpCurrencyAmount.handle( - ($) -> assertThat($.value()).isEqualTo(UnsignedLong.ZERO), - ($) -> fail() - ); - + void handleWithNulls() { + CurrencyAmount amount = () -> false; // null xrpCurrencyAmountHandler assertThrows(NullPointerException.class, () -> - xrpCurrencyAmount.handle(null, ($) -> new Object()) + amount.handle(null, ($) -> new Object(), ($) -> new Object()) ); // null issuedCurrencyAmountConsumer assertThrows(NullPointerException.class, () -> - xrpCurrencyAmount.handle(($) -> new Object(), null) + amount.handle(($) -> new Object(), null, ($) -> new Object()) ); + // null mpTokenAmount + assertThrows(NullPointerException.class, () -> + amount.handle(($) -> new Object(), ($) -> new Object(), null) + ); + } + + @Test + void handleUnhandled() { + CurrencyAmount amount = () -> false; // Unhandled... CurrencyAmount currencyAmount = () -> false; assertThrows(IllegalStateException.class, () -> - currencyAmount.handle(($) -> new Object(), ($) -> new Object()) + currencyAmount.handle(($) -> new Object(), ($) -> new Object(), ($) -> new Object()) + ); + } + + @Test + public void handleXrp() { + XrpCurrencyAmount xrpCurrencyAmount = XrpCurrencyAmount.ofDrops(0L); + + xrpCurrencyAmount.handle( + ($) -> assertThat($.value()).isEqualTo(UnsignedLong.ZERO), + ($) -> fail(), + ($) -> fail() ); } @@ -96,17 +110,10 @@ public void handleIssuance() { issuedCurrencyAmount.handle( ($) -> fail(), - ($) -> assertThat($.value()).isEqualTo("100") + ($) -> assertThat($.value()).isEqualTo("100"), + ($) -> fail() ); - // null xrpCurrencyAmountHandler - assertThrows(NullPointerException.class, () -> - issuedCurrencyAmount.handle(null, ($) -> new Object()) - ); - // null issuedCurrencyAmountConsumer - assertThrows(NullPointerException.class, () -> - issuedCurrencyAmount.handle(($) -> new Object(), null) - ); } @Test @@ -115,24 +122,10 @@ public void mapXrp() { String actual = xrpCurrencyAmount.map( ($) -> "success", + ($) -> "fail", ($) -> "fail" ); assertThat(actual).isEqualTo("success"); - - // null xrpCurrencyAmountHandler - assertThrows(NullPointerException.class, () -> - xrpCurrencyAmount.map(null, ($) -> new Object()) - ); - // null issuedCurrencyAmountConsumer - assertThrows(NullPointerException.class, () -> - xrpCurrencyAmount.map(($) -> new Object(), null) - ); - - // Unhandled... - CurrencyAmount currencyAmount = () -> false; - assertThrows(IllegalStateException.class, () -> - currencyAmount.map(($) -> new Object(), ($) -> new Object()) - ); } @Test @@ -145,18 +138,10 @@ public void mapIssuance() { String actual = issuedCurrencyAmount.map( ($) -> "fail", - ($) -> "success" + ($) -> "success", + ($) -> "fail" ); assertThat(actual).isEqualTo("success"); - - // null xrpCurrencyAmountHandler - assertThrows(NullPointerException.class, () -> - issuedCurrencyAmount.map(null, ($) -> new Object()) - ); - // null issuedCurrencyAmountConsumer - assertThrows(NullPointerException.class, () -> - issuedCurrencyAmount.map(($) -> new Object(), null) - ); } /** @@ -229,7 +214,8 @@ private void currencyTestHelper(String currencyCode) throws JsonProcessingExcept final String finalCurrencyCode = currencyCode; decodedPayment.amount().handle( xrpCurrencyAmount -> fail(), - issuedCurrencyAmount -> assertThat(issuedCurrencyAmount.currency()).isEqualTo(finalCurrencyCode) + issuedCurrencyAmount -> assertThat(issuedCurrencyAmount.currency()).isEqualTo(finalCurrencyCode), + mpTokenAmount -> fail() ); } diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/NegativeTransactionMetadataTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/NegativeTransactionMetadataTest.java index e5a09a6c7..c2bcedbce 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/NegativeTransactionMetadataTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/NegativeTransactionMetadataTest.java @@ -276,6 +276,13 @@ private void handleMetaLedgerObject(MetaOfferObject metaOfferObject) { } else { assertThat(issuedCurrencyAmount.isNegative()).isFalse(); } + }, + mpTokenAmount -> { + if (mpTokenAmount.value().startsWith("-")) { + assertThat(mpTokenAmount.isNegative()).isTrue(); + } else { + assertThat(mpTokenAmount.isNegative()).isFalse(); + } } ); }); @@ -289,7 +296,9 @@ private void handleMetaLedgerObject(MetaNfTokenOfferObject metaNfTokenOfferObjec xrpCurrencyAmount -> assertThat(xrpCurrencyAmount.isNegative()).isEqualTo( xrpCurrencyAmount.toXrp().signum() < 0), issuedCurrencyAmount -> assertThat(issuedCurrencyAmount.isNegative()).isEqualTo( - issuedCurrencyAmount.value().startsWith("-")) + issuedCurrencyAmount.value().startsWith("-")), + mpTokenAmount -> assertThat(mpTokenAmount.isNegative()).isEqualTo( + mpTokenAmount.value().startsWith("-")) )); } } \ No newline at end of file From a609c68a0346a1acb86b97343a793dec7191d320 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sun, 20 Oct 2024 10:59:56 -0400 Subject: [PATCH 03/10] add potential alternative to clawback amounts --- .../xrpl4j/model/transactions/Clawback.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java index 8c5833d63..2970fdc4d 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Clawback.java @@ -1,6 +1,7 @@ package org.xrpl.xrpl4j.model.transactions; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.annotations.Beta; @@ -56,4 +57,24 @@ default TransactionFlags flags() { @JsonProperty("MPTokenHolder") Optional
mpTokenHolder(); + // TODO: I don't love that this is now a CurrencyAmount, because it can only ever be an IssuedCurrencyAmount + // or MptAmount, and mpTokenHolder can only be present when amount is an MptAmount. + // This might work, but we'd need to do some wonky jackson stuff to make it work + /*@JsonUnwrapped + ClawbackAmount amount(); + + interface ClawbackAmount {} + + @Immutable + @JsonSerialize(as = ImmutableIssuedCurrencyClawbackAmount.class) + @JsonDeserialize(as = ImmutableIssuedCurrencyClawbackAmount.class) + interface IssuedCurrencyClawbackAmount extends ClawbackAmount { + IssuedCurrencyAmount amount(); + } + + interface MptClawbackAmount extends ClawbackAmount { + MpTokenAmount amount(); + + Optional
mpTokenHolder(); + }*/ } From ce3fff815847c4d26a9043220e2ce9e0a673257c Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Mon, 21 Oct 2024 11:25:06 -0400 Subject: [PATCH 04/10] add MPT ledger objects --- .../xrpl/xrpl4j/model/flags/MpTokenFlags.java | 83 ++++++++++ .../model/flags/MpTokenIssuanceFlags.java | 151 ++++++++++++++++++ .../MpTokenObjectAmountDeserializer.java | 28 ++++ ...ava => MpTokenObjectAmountSerializer.java} | 12 +- .../modules/MptMaximumAmountDeserializer.java | 28 ---- .../xrpl4j/model/ledger/LedgerObject.java | 10 +- .../model/ledger/MpTokenIssuanceObject.java | 104 ++++++++++++ .../xrpl4j/model/ledger/MpTokenObject.java | 97 +++++++++++ .../transactions/MpTokenIssuanceCreate.java | 2 +- .../xrpl4j/model/transactions/Wrappers.java | 15 +- 10 files changed, 486 insertions(+), 44 deletions(-) create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java rename xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/{MptMaximumAmountSerializer.java => MpTokenObjectAmountSerializer.java} (52%) delete mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java new file mode 100644 index 000000000..376eafac5 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java @@ -0,0 +1,83 @@ +package org.xrpl.xrpl4j.model.flags; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: core + * %% + * Copyright (C) 2020 - 2023 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +/** + * A set of static {@link Flags} which can be set on {@link org.xrpl.xrpl4j.model.ledger.MpTokenObject}s. + */ +public class MpTokenFlags extends Flags { + + /** + * Constant for an unset flag. + */ + public static final MpTokenFlags UNSET = new MpTokenFlags(0); + + /** + * Constant {@link MpTokenFlags} for the {@code lsfMPTLocked} account flag. + */ + public static final MpTokenFlags LOCKED = new MpTokenFlags(0x00000001); + /** + * Constant {@link MpTokenFlags} for the {@code lsfMPTCanLock} account flag. + */ + public static final MpTokenFlags AUTHORIZED = new MpTokenFlags(0x00000002); + + /** + * Required-args Constructor. + * + * @param value The long-number encoded flags value of this {@link MpTokenFlags}. + */ + private MpTokenFlags(final long value) { + super(value); + } + + /** + * Construct {@link MpTokenFlags} with a given value. + * + * @param value The long-number encoded flags value of this {@link MpTokenFlags}. + * + * @return New {@link MpTokenFlags}. + */ + public static MpTokenFlags of(long value) { + return new MpTokenFlags(value); + } + + /** + * If set, indicates that all balances are locked. + * + * @return {@code true} if {@code lsfMPTLocked} is set, otherwise {@code false}. + */ + public boolean lsfMptLocked() { + return this.isSet(MpTokenFlags.LOCKED); + } + + /** + * (Only applicable for allow-listing) If set, indicates that the issuer has authorized the holder for the MPT. This + * flag can be set using a MPTokenAuthorize transaction; it can also be "un-set" using a MPTokenAuthorize transaction + * specifying the tfMPTUnauthorize flag. + * + * @return {@code true} if {@code lsfMPTAuthorized} is set, otherwise {@code false}. + */ + public boolean lsfMptAuthorized() { + return this.isSet(MpTokenFlags.AUTHORIZED); + } + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java new file mode 100644 index 000000000..f34aae9f9 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java @@ -0,0 +1,151 @@ +package org.xrpl.xrpl4j.model.flags; + +/*- + * ========================LICENSE_START================================= + * xrpl4j :: core + * %% + * Copyright (C) 2020 - 2023 XRPL Foundation and its contributors + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +/** + * A set of static {@link Flags} which can be set on {@link org.xrpl.xrpl4j.model.ledger.MpTokenIssuanceObject}s. + */ +public class MpTokenIssuanceFlags extends Flags { + + /** + * Constant for an unset flag. + */ + public static final MpTokenIssuanceFlags UNSET = new MpTokenIssuanceFlags(0); + + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTLocked} account flag. + */ + public static final MpTokenIssuanceFlags LOCKED = new MpTokenIssuanceFlags(0x00000001); + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTCanLock} account flag. + */ + public static final MpTokenIssuanceFlags CAN_LOCK = new MpTokenIssuanceFlags(0x00000002); + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTRequireAuth} account flag. + */ + public static final MpTokenIssuanceFlags REQUIRE_AUTH = new MpTokenIssuanceFlags(0x00000004); + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTCanEscrow} account flag. + */ + public static final MpTokenIssuanceFlags CAN_ESCROW = new MpTokenIssuanceFlags(0x00000008); + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTCanTrade} account flag. + */ + public static final MpTokenIssuanceFlags CAN_TRADE = new MpTokenIssuanceFlags(0x00000010); + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTCanTransfer} account flag. + */ + public static final MpTokenIssuanceFlags CAN_TRANSFER = new MpTokenIssuanceFlags(0x00000020); + /** + * Constant {@link MpTokenIssuanceFlags} for the {@code lsfMPTCanClawback} account flag. + */ + public static final MpTokenIssuanceFlags CAN_CLAWBACK = new MpTokenIssuanceFlags(0x00000040); + + /** + * Required-args Constructor. + * + * @param value The long-number encoded flags value of this {@link MpTokenIssuanceFlags}. + */ + private MpTokenIssuanceFlags(final long value) { + super(value); + } + + /** + * Construct {@link MpTokenIssuanceFlags} with a given value. + * + * @param value The long-number encoded flags value of this {@link MpTokenIssuanceFlags}. + * + * @return New {@link MpTokenIssuanceFlags}. + */ + public static MpTokenIssuanceFlags of(long value) { + return new MpTokenIssuanceFlags(value); + } + + /** + * If set, indicates that all balances are locked. + * + * @return {@code true} if {@code lsfMPTLocked} is set, otherwise {@code false}. + */ + public boolean lsfMptLocked() { + return this.isSet(MpTokenIssuanceFlags.LOCKED); + } + + /** + * If set, indicates that the issuer can lock an individual balance or all balances of this MPT. If not set, the MPT + * cannot be locked in any way. + * + * @return {@code true} if {@code lsfMPTCanLock} is set, otherwise {@code false}. + */ + public boolean lsfMptCanLock() { + return this.isSet(MpTokenIssuanceFlags.CAN_LOCK); + } + + /** + * If set, indicates that individual holders must be authorized. This enables issuers to limit who can hold their + * assets. + * + * @return {@code true} if {@code lsfMPTRequireAuth} is set, otherwise {@code false}. + */ + public boolean lsfMptRequireAuth() { + return this.isSet(MpTokenIssuanceFlags.REQUIRE_AUTH); + } + + /** + * If set, indicates that individual holders can place their balances into an escrow. + * + * @return {@code true} if {@code lsfMPTCanEscrow} is set, otherwise {@code false}. + */ + public boolean lsfMptCanEscrow() { + return this.isSet(MpTokenIssuanceFlags.CAN_ESCROW); + } + + /** + * If set, indicates that individual holders can trade their balances using the XRP Ledger DEX or AMM. + * + * @return {@code true} if {@code lsfMPTCanTrade} is set, otherwise {@code false}. + */ + public boolean lsfMptCanTrade() { + return this.isSet(MpTokenIssuanceFlags.CAN_TRADE); + } + + /** + * If set, indicates that tokens held by non-issuers may be transferred to other accounts. If not set, indicates that + * tokens held by non-issuers may not be transferred except back to the issuer; this enables use-cases like store + * credit. + * + * @return {@code true} if {@code lsfMPTCanTransfer} is set, otherwise {@code false}. + */ + public boolean lsfMptCanTransfer() { + return this.isSet(MpTokenIssuanceFlags.CAN_TRANSFER); + } + + /** + * If set, indicates that the issuer may use the Clawback transaction to clawback value from individual holders. + * + * @return {@code true} if {@code lsfMPTCanClawback} is set, otherwise {@code false}. + */ + public boolean lsfMptCanClawback() { + return this.isSet(MpTokenIssuanceFlags.CAN_CLAWBACK); + } + + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java new file mode 100644 index 000000000..566975e68 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java @@ -0,0 +1,28 @@ +package org.xrpl.xrpl4j.model.jackson.modules; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.google.common.primitives.UnsignedLong; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; + +import java.io.IOException; + +/** + * Custom Jackson deserializer for {@link MpTokenObjectAmount}s. + */ +public class MpTokenObjectAmountDeserializer extends StdDeserializer { + + /** + * No-args constructor. + */ + public MpTokenObjectAmountDeserializer() { + super(MpTokenObjectAmount.class); + } + + @Override + public MpTokenObjectAmount deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { + // sfMaximumAmount is an STUInt64s, which in JSON is represented as a hex-encoded String. + return MpTokenObjectAmount.of(UnsignedLong.valueOf(jsonParser.getText(), 16)); + } +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountSerializer.java similarity index 52% rename from xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java rename to xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountSerializer.java index f1efdc208..d7d72bb88 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountSerializer.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountSerializer.java @@ -3,24 +3,24 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; -import org.xrpl.xrpl4j.model.transactions.MptMaximumAmount; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; import java.io.IOException; /** - * Custom Jackson serializer for {@link MptMaximumAmount}s. + * Custom Jackson serializer for {@link MpTokenObjectAmount}s. */ -public class MptMaximumAmountSerializer extends StdScalarSerializer { +public class MpTokenObjectAmountSerializer extends StdScalarSerializer { /** * No-args constructor. */ - public MptMaximumAmountSerializer() { - super(MptMaximumAmount.class, false); + public MpTokenObjectAmountSerializer() { + super(MpTokenObjectAmount.class, false); } @Override - public void serialize(MptMaximumAmount count, JsonGenerator gen, SerializerProvider provider) throws IOException { + public void serialize(MpTokenObjectAmount count, JsonGenerator gen, SerializerProvider provider) throws IOException { // sfMaximumAmount is an STUInt64s, which in JSON is represented as a hex-encoded String. gen.writeString(count.value().toString(16)); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java deleted file mode 100644 index 9cf7963f7..000000000 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MptMaximumAmountDeserializer.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.xrpl.xrpl4j.model.jackson.modules; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import com.google.common.primitives.UnsignedLong; -import org.xrpl.xrpl4j.model.transactions.MptMaximumAmount; - -import java.io.IOException; - -/** - * Custom Jackson deserializer for {@link MptMaximumAmount}s. - */ -public class MptMaximumAmountDeserializer extends StdDeserializer { - - /** - * No-args constructor. - */ - public MptMaximumAmountDeserializer() { - super(MptMaximumAmount.class); - } - - @Override - public MptMaximumAmount deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { - // sfMaximumAmount is an STUInt64s, which in JSON is represented as a hex-encoded String. - return MptMaximumAmount.of(UnsignedLong.valueOf(jsonParser.getText(), 16)); - } -} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/LedgerObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/LedgerObject.java index 56a5b3bcb..02f1164aa 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/LedgerObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/LedgerObject.java @@ -62,6 +62,8 @@ @JsonSubTypes.Type(value = ImmutableXChainOwnedClaimIdObject.class, name = "XChainOwnedClaimID"), @JsonSubTypes.Type(value = ImmutableDidObject.class, name = "DID"), @JsonSubTypes.Type(value = ImmutableOracleObject.class, name = "Oracle"), + @JsonSubTypes.Type(value = ImmutableMpTokenIssuanceObject.class, name = "MPTokenIssuance"), + @JsonSubTypes.Type(value = ImmutableMpTokenObject.class, name = "MPToken"), }) // TODO: Uncomment subtypes as we implement public interface LedgerObject { @@ -202,7 +204,13 @@ enum LedgerEntryType { * Its API is subject to change.

*/ @Beta - ORACLE("Oracle"); + ORACLE("Oracle"), + + @Beta + MP_TOKEN_ISSUANCE("MPTokenIssuance"), + + @Beta + MP_TOKEN("MPToken"); private final String value; diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java new file mode 100644 index 000000000..83a3dfcaa --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java @@ -0,0 +1,104 @@ +package org.xrpl.xrpl4j.model.ledger; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedInteger; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceFlags; +import org.xrpl.xrpl4j.model.transactions.Address; +import org.xrpl.xrpl4j.model.transactions.AssetScale; +import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; +import org.xrpl.xrpl4j.model.transactions.TransferFee; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenIssuanceObject.class) +@JsonDeserialize(as = ImmutableMpTokenIssuanceObject.class) +public interface MpTokenIssuanceObject extends LedgerObject { + + /** + * Construct a {@code MpTokenIssuanceObject} builder. + * + * @return An {@link ImmutableMpTokenIssuanceObject.Builder}. + */ + static ImmutableMpTokenIssuanceObject.Builder builder() { + return ImmutableMpTokenIssuanceObject.builder(); + } + + @JsonProperty("LedgerEntryType") + @Value.Derived + default LedgerEntryType ledgerEntryType() { + return LedgerEntryType.MP_TOKEN_ISSUANCE; + } + + @JsonProperty("Flags") + MpTokenIssuanceFlags flags(); + + @JsonProperty("Issuer") + Address issuer(); + + @JsonProperty("AssetScale") + AssetScale assetScale(); + + @JsonProperty("MaximumAmount") + MpTokenObjectAmount maximumAmount(); + + @JsonProperty("OutstandingAmount") + MpTokenObjectAmount outstandingAmount(); + + @JsonProperty("TransferFee") + TransferFee transferFee(); + + @JsonProperty("MPTokenMetadata") + Optional mpTokenMetadata(); + + /** + * The identifying hash of the transaction that most recently modified this object. + * + * @return A {@link Hash256} containing the previous transaction hash. + */ + @JsonProperty("PreviousTxnID") + Hash256 previousTransactionId(); + + /** + * The index of the ledger that contains the transaction that most recently modified this object. + * + * @return An {@link UnsignedInteger} representing the previous transaction ledger sequence. + */ + @JsonProperty("PreviousTxnLgrSeq") + UnsignedInteger previousTransactionLedgerSequence(); + + /** + * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an + * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence + * number. + * + * @return An {@link UnsignedInteger} representing the account sequence number. + */ + @JsonProperty("Sequence") + UnsignedInteger sequence(); + + /** + * A hint indicating which page of the 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 An {@link Optional} of type {@link String} containing the owner node hint. + */ + @JsonProperty("OwnerNode") + Optional ownerNode(); + + /** + * The unique ID of this {@link MpTokenIssuanceObject}. + * + * @return A {@link Hash256} containing the ID. + */ + Hash256 index(); +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java new file mode 100644 index 000000000..6de20cd1a --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java @@ -0,0 +1,97 @@ +package org.xrpl.xrpl4j.model.ledger; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedInteger; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenFlags; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceFlags; +import org.xrpl.xrpl4j.model.transactions.Address; +import org.xrpl.xrpl4j.model.transactions.AssetScale; +import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; +import org.xrpl.xrpl4j.model.transactions.TransferFee; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenObject.class) +@JsonDeserialize(as = ImmutableMpTokenObject.class) +public interface MpTokenObject extends LedgerObject { + + /** + * Construct a {@code MpTokenObject} builder. + * + * @return An {@link ImmutableMpTokenObject.Builder}. + */ + static ImmutableMpTokenObject.Builder builder() { + return ImmutableMpTokenObject.builder(); + } + + @JsonProperty("LedgerEntryType") + @Value.Derived + default LedgerEntryType ledgerEntryType() { + return LedgerEntryType.MP_TOKEN; + } + + @JsonProperty("Flags") + MpTokenFlags flags(); + + @JsonProperty("Account") + Address account(); + + @JsonProperty("MPTokenIssuanceID") + MpTokenIssuanceId mpTokenIssuanceId(); + + @JsonProperty("MPTAmount") + MpTokenObjectAmount mptAmount(); + + /** + * The identifying hash of the transaction that most recently modified this object. + * + * @return A {@link Hash256} containing the previous transaction hash. + */ + @JsonProperty("PreviousTxnID") + Hash256 previousTransactionId(); + + /** + * The index of the ledger that contains the transaction that most recently modified this object. + * + * @return An {@link UnsignedInteger} representing the previous transaction ledger sequence. + */ + @JsonProperty("PreviousTxnLgrSeq") + UnsignedInteger previousTransactionLedgerSequence(); + + /** + * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an + * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence + * number. + * + * @return An {@link UnsignedInteger} representing the account sequence number. + */ + @JsonProperty("Sequence") + UnsignedInteger sequence(); + + /** + * A hint indicating which page of the 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 An {@link Optional} of type {@link String} containing the owner node hint. + */ + @JsonProperty("OwnerNode") + Optional ownerNode(); + + /** + * The unique ID of this {@link MpTokenObject}. + * + * @return A {@link Hash256} containing the ID. + */ + Hash256 index(); +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java index 189ed54cd..8f24ced37 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java @@ -41,7 +41,7 @@ default MpTokenIssuanceCreateFlags flags() { Optional transferFee(); @JsonProperty("MaximumAmount") - Optional maximumAmount(); + Optional maximumAmount(); @JsonProperty("MPTokenMetadata") Optional mpTokenMetadata(); diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java index cbc89b8ac..4dd1be54b 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/Wrappers.java @@ -20,7 +20,6 @@ * =========================LICENSE_END================================== */ -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonRawValue; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -53,8 +52,8 @@ import org.xrpl.xrpl4j.model.jackson.modules.MarkerSerializer; import org.xrpl.xrpl4j.model.jackson.modules.MpTokenIssuanceIdDeserializer; import org.xrpl.xrpl4j.model.jackson.modules.MpTokenIssuanceIdSerializer; -import org.xrpl.xrpl4j.model.jackson.modules.MptMaximumAmountDeserializer; -import org.xrpl.xrpl4j.model.jackson.modules.MptMaximumAmountSerializer; +import org.xrpl.xrpl4j.model.jackson.modules.MpTokenObjectAmountDeserializer; +import org.xrpl.xrpl4j.model.jackson.modules.MpTokenObjectAmountSerializer; import org.xrpl.xrpl4j.model.jackson.modules.NetworkIdDeserializer; import org.xrpl.xrpl4j.model.jackson.modules.NetworkIdSerializer; import org.xrpl.xrpl4j.model.jackson.modules.NfTokenIdDeserializer; @@ -799,13 +798,13 @@ public String toString() { @Value.Immutable @Wrapped - @JsonSerialize(as = MptMaximumAmount.class, using = MptMaximumAmountSerializer.class) - @JsonDeserialize(as = MptMaximumAmount.class, using = MptMaximumAmountDeserializer.class) + @JsonSerialize(as = MpTokenObjectAmount.class, using = MpTokenObjectAmountSerializer.class) + @JsonDeserialize(as = MpTokenObjectAmount.class, using = MpTokenObjectAmountDeserializer.class) @Beta - abstract static class _MptMaximumAmount extends Wrapper implements Serializable { + abstract static class _MpTokenObjectAmount extends Wrapper implements Serializable { - public static MptMaximumAmount of(long amount) { - return MptMaximumAmount.of(UnsignedLong.valueOf(amount)); + public static MpTokenObjectAmount of(long amount) { + return MpTokenObjectAmount.of(UnsignedLong.valueOf(amount)); } @Override From 4609b30461a33c8a784910b09267158a2d713073 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Mon, 21 Oct 2024 12:25:32 -0400 Subject: [PATCH 05/10] add meta objects --- .../model/ledger/MpTokenIssuanceObject.java | 2 +- .../metadata/MetaLedgerEntryType.java | 8 ++ .../metadata/MetaMpTokenIssuanceObject.java | 85 +++++++++++++++++++ .../metadata/MetaMpTokenObject.java | 75 ++++++++++++++++ .../metadata/MetaLedgerEntryTypeTest.java | 6 +- 5 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenIssuanceObject.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java index 83a3dfcaa..a98f70bed 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java @@ -21,7 +21,7 @@ public interface MpTokenIssuanceObject extends LedgerObject { /** - * Construct a {@code MpTokenIssuanceObject} builder. + * Construct a {@code MetaMpTokenIssuanceObject} builder. * * @return An {@link ImmutableMpTokenIssuanceObject.Builder}. */ diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryType.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryType.java index f38c96546..5069172f6 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryType.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryType.java @@ -47,6 +47,10 @@ public interface MetaLedgerEntryType { @Beta MetaLedgerEntryType ORACLE = MetaLedgerEntryType.of("Oracle"); + MetaLedgerEntryType MP_TOKEN_ISSUANCE = MetaLedgerEntryType.of("MPTokenIssuance"); + MetaLedgerEntryType MP_TOKEN = MetaLedgerEntryType.of("MPToken"); + + /** * Construct a new {@link MetaLedgerEntryType} from a {@link String}. * @@ -103,6 +107,10 @@ default Class ledgerObjectType() { return MetaDidObject.class; case "Oracle": return MetaOracleObject.class; + case "MPTokenIssuance": + return MetaMpTokenIssuanceObject.class; + case "MPToken": + return MetaMpTokenObject.class; default: return MetaUnknownObject.class; } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenIssuanceObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenIssuanceObject.java new file mode 100644 index 000000000..c06e8d30d --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenIssuanceObject.java @@ -0,0 +1,85 @@ +package org.xrpl.xrpl4j.model.transactions.metadata; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedInteger; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceFlags; +import org.xrpl.xrpl4j.model.ledger.ImmutableMpTokenIssuanceObject; +import org.xrpl.xrpl4j.model.ledger.LedgerObject; +import org.xrpl.xrpl4j.model.transactions.Address; +import org.xrpl.xrpl4j.model.transactions.AssetScale; +import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; +import org.xrpl.xrpl4j.model.transactions.TransferFee; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMetaMpTokenIssuanceObject.class) +@JsonDeserialize(as = ImmutableMetaMpTokenIssuanceObject.class) +public interface MetaMpTokenIssuanceObject extends MetaLedgerObject { + + @JsonProperty("Flags") + Optional flags(); + + @JsonProperty("Issuer") + Optional
issuer(); + + @JsonProperty("AssetScale") + Optional assetScale(); + + @JsonProperty("MaximumAmount") + Optional maximumAmount(); + + @JsonProperty("OutstandingAmount") + Optional outstandingAmount(); + + @JsonProperty("TransferFee") + Optional transferFee(); + + @JsonProperty("MPTokenMetadata") + Optional mpTokenMetadata(); + + /** + * The identifying hash of the transaction that most recently modified this object. + * + * @return A {@link Hash256} containing the previous transaction hash. + */ + @JsonProperty("PreviousTxnID") + Optional previousTransactionId(); + + /** + * The index of the ledger that contains the transaction that most recently modified this object. + * + * @return An {@link UnsignedInteger} representing the previous transaction ledger sequence. + */ + @JsonProperty("PreviousTxnLgrSeq") + Optional previousTransactionLedgerSequence(); + + /** + * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an + * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence + * number. + * + * @return An {@link UnsignedInteger} representing the account sequence number. + */ + @JsonProperty("Sequence") + Optional sequence(); + + /** + * A hint indicating which page of the 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 An {@link Optional} of type {@link String} containing the owner node hint. + */ + @JsonProperty("OwnerNode") + Optional ownerNode(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java new file mode 100644 index 000000000..6cbed0782 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java @@ -0,0 +1,75 @@ +package org.xrpl.xrpl4j.model.transactions.metadata; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedInteger; +import org.immutables.value.Value; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenFlags; +import org.xrpl.xrpl4j.model.ledger.ImmutableMpTokenObject; +import org.xrpl.xrpl4j.model.ledger.LedgerObject; +import org.xrpl.xrpl4j.model.transactions.Address; +import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMetaMpTokenObject.class) +@JsonDeserialize(as = ImmutableMetaMpTokenObject.class) +public interface MetaMpTokenObject extends MetaLedgerObject { + + @JsonProperty("Flags") + Optional flags(); + + @JsonProperty("Account") + Optional
account(); + + @JsonProperty("MPTokenIssuanceID") + Optional mpTokenIssuanceId(); + + @JsonProperty("MPTAmount") + Optional mptAmount(); + + /** + * The identifying hash of the transaction that most recently modified this object. + * + * @return A {@link Hash256} containing the previous transaction hash. + */ + @JsonProperty("PreviousTxnID") + Optional previousTransactionId(); + + /** + * The index of the ledger that contains the transaction that most recently modified this object. + * + * @return An {@link UnsignedInteger} representing the previous transaction ledger sequence. + */ + @JsonProperty("PreviousTxnLgrSeq") + Optional previousTransactionLedgerSequence(); + + /** + * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an + * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence + * number. + * + * @return An {@link UnsignedInteger} representing the account sequence number. + */ + @JsonProperty("Sequence") + Optional sequence(); + + /** + * A hint indicating which page of the 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 An {@link Optional} of type {@link String} containing the owner node hint. + */ + @JsonProperty("OwnerNode") + Optional ownerNode(); + +} diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryTypeTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryTypeTest.java index 20045d4e1..7df46216f 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryTypeTest.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaLedgerEntryTypeTest.java @@ -8,8 +8,6 @@ import org.immutables.value.Value; import org.junit.jupiter.api.Test; import org.xrpl.xrpl4j.model.AbstractJsonTest; -import org.xrpl.xrpl4j.model.ledger.AccountRootObject; -import org.xrpl.xrpl4j.model.ledger.OracleObject; class MetaLedgerEntryTypeTest extends AbstractJsonTest { @@ -37,7 +35,7 @@ void testConstants() { .isEqualTo("XChainOwnedCreateAccountClaimID"); assertThat(MetaLedgerEntryType.XCHAIN_OWNED_CLAIM_ID.value()).isEqualTo("XChainOwnedClaimID"); assertThat(MetaLedgerEntryType.DID.value()).isEqualTo("DID"); - assertThat(MetaLedgerEntryType.ORACLE.value()).isEqualTo("Oracle"); + assertThat(MetaLedgerEntryType.MP_TOKEN.value()).isEqualTo("Oracle"); } @Test @@ -66,7 +64,7 @@ void testLedgerObjectType() { MetaXChainOwnedClaimIdObject.class ); assertThat(MetaLedgerEntryType.DID.ledgerObjectType()).isEqualTo(MetaDidObject.class); - assertThat(MetaLedgerEntryType.ORACLE.ledgerObjectType()).isEqualTo(MetaOracleObject.class); + assertThat(MetaLedgerEntryType.MP_TOKEN.ledgerObjectType()).isEqualTo(MetaOracleObject.class); } @Test From a44cfde93833d1b2b504e275ab7f4ea6cb7d2633 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Mon, 21 Oct 2024 12:29:14 -0400 Subject: [PATCH 06/10] add transactions to signature utils --- .../xrpl4j/crypto/signing/SignatureUtils.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/crypto/signing/SignatureUtils.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/crypto/signing/SignatureUtils.java index 8f2b39fef..c44d7db2c 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/crypto/signing/SignatureUtils.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/crypto/signing/SignatureUtils.java @@ -49,6 +49,10 @@ import org.xrpl.xrpl4j.model.transactions.EscrowCancel; import org.xrpl.xrpl4j.model.transactions.EscrowCreate; import org.xrpl.xrpl4j.model.transactions.EscrowFinish; +import org.xrpl.xrpl4j.model.transactions.MpTokenAuthorize; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceCreate; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceDestroy; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceSet; import org.xrpl.xrpl4j.model.transactions.NfTokenAcceptOffer; import org.xrpl.xrpl4j.model.transactions.NfTokenBurn; import org.xrpl.xrpl4j.model.transactions.NfTokenCancelOffer; @@ -391,6 +395,22 @@ public SingleSignedTransaction addSignatureToTransact transactionWithSignature = OracleDelete.builder().from((OracleDelete) transaction) .transactionSignature(signature) .build(); + } else if (MpTokenAuthorize.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignature = MpTokenAuthorize.builder().from((MpTokenAuthorize) transaction) + .transactionSignature(signature) + .build(); + } else if (MpTokenIssuanceCreate.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignature = MpTokenIssuanceCreate.builder().from((MpTokenIssuanceCreate) transaction) + .transactionSignature(signature) + .build(); + } else if (MpTokenIssuanceDestroy.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignature = MpTokenIssuanceDestroy.builder().from((MpTokenIssuanceDestroy) transaction) + .transactionSignature(signature) + .build(); + } else if (MpTokenIssuanceSet.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignature = MpTokenIssuanceSet.builder().from((MpTokenIssuanceSet) transaction) + .transactionSignature(signature) + .build(); } else { // Should never happen, but will in a unit test if we miss one. throw new IllegalArgumentException("Signing fields could not be added to the transaction."); @@ -602,6 +622,22 @@ public T addMultiSignaturesToTransaction(T transaction, transactionWithSignatures = OracleDelete.builder().from((OracleDelete) transaction) .signers(signers) .build(); + } else if (MpTokenAuthorize.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignatures = MpTokenAuthorize.builder().from((MpTokenAuthorize) transaction) + .signers(signers) + .build(); + } else if (MpTokenIssuanceCreate.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignatures = MpTokenIssuanceCreate.builder().from((MpTokenIssuanceCreate) transaction) + .signers(signers) + .build(); + } else if (MpTokenIssuanceDestroy.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignatures = MpTokenIssuanceDestroy.builder().from((MpTokenIssuanceDestroy) transaction) + .signers(signers) + .build(); + } else if (MpTokenIssuanceSet.class.isAssignableFrom(transaction.getClass())) { + transactionWithSignatures = MpTokenIssuanceSet.builder().from((MpTokenIssuanceSet) transaction) + .signers(signers) + .build(); } else { // Should never happen, but will in a unit test if we miss one. throw new IllegalArgumentException("Signing fields could not be added to the transaction."); From c3a8b7194edcd70ee71a0a7b9a85b015c1abb2b0 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 9 Nov 2024 10:50:30 -0500 Subject: [PATCH 07/10] PR feedback. Deserialize mpt amounts as base 10 --- .../xrpl4j/model/flags/MpTokenAuthorizeFlags.java | 11 ----------- .../org/xrpl/xrpl4j/model/flags/MpTokenFlags.java | 11 ----------- .../model/flags/MpTokenIssuanceCreateFlags.java | 11 ----------- .../xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java | 11 ----------- .../xrpl4j/model/flags/MpTokenIssuanceSetFlags.java | 11 ----------- .../modules/MpTokenObjectAmountDeserializer.java | 5 +++-- .../xrpl/xrpl4j/model/transactions/MpTokenAmount.java | 8 ++++++++ 7 files changed, 11 insertions(+), 57 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java index 1d8217139..97dbd3647 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenAuthorizeFlags.java @@ -39,17 +39,6 @@ private MpTokenAuthorizeFlags(long value) { private MpTokenAuthorizeFlags() { } - /** - * Construct {@link MpTokenAuthorizeFlags} with a given value. - * - * @param value The long-number encoded flags value of this {@link MpTokenAuthorizeFlags}. - * - * @return New {@link MpTokenAuthorizeFlags}. - */ - public static MpTokenAuthorizeFlags of(long value) { - return new MpTokenAuthorizeFlags(value); - } - /** * Construct an empty instance of {@link MpTokenAuthorizeFlags}. Transactions with empty flags will not be serialized * with a {@code Flags} field. diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java index 376eafac5..bcfc035f2 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenFlags.java @@ -49,17 +49,6 @@ private MpTokenFlags(final long value) { super(value); } - /** - * Construct {@link MpTokenFlags} with a given value. - * - * @param value The long-number encoded flags value of this {@link MpTokenFlags}. - * - * @return New {@link MpTokenFlags}. - */ - public static MpTokenFlags of(long value) { - return new MpTokenFlags(value); - } - /** * If set, indicates that all balances are locked. * diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java index b142404f6..8d5b58415 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceCreateFlags.java @@ -91,17 +91,6 @@ private static MpTokenIssuanceCreateFlags of( ); } - /** - * Construct {@link MpTokenIssuanceCreateFlags} with a given value. - * - * @param value The long-number encoded flags value of this {@link MpTokenIssuanceCreateFlags}. - * - * @return New {@link MpTokenIssuanceCreateFlags}. - */ - public static MpTokenIssuanceCreateFlags of(long value) { - return new MpTokenIssuanceCreateFlags(value); - } - /** * Construct an empty instance of {@link MpTokenIssuanceCreateFlags}. Transactions with empty flags will not be * serialized with a {@code Flags} field. diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java index f34aae9f9..dea718027 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceFlags.java @@ -69,17 +69,6 @@ private MpTokenIssuanceFlags(final long value) { super(value); } - /** - * Construct {@link MpTokenIssuanceFlags} with a given value. - * - * @param value The long-number encoded flags value of this {@link MpTokenIssuanceFlags}. - * - * @return New {@link MpTokenIssuanceFlags}. - */ - public static MpTokenIssuanceFlags of(long value) { - return new MpTokenIssuanceFlags(value); - } - /** * If set, indicates that all balances are locked. * diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java index dcc2f018a..19a1a5a37 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/flags/MpTokenIssuanceSetFlags.java @@ -43,17 +43,6 @@ private MpTokenIssuanceSetFlags(long value) { private MpTokenIssuanceSetFlags() { } - /** - * Construct {@link MpTokenIssuanceSetFlags} with a given value. - * - * @param value The long-number encoded flags value of this {@link MpTokenIssuanceSetFlags}. - * - * @return New {@link MpTokenIssuanceSetFlags}. - */ - public static MpTokenIssuanceSetFlags of(long value) { - return new MpTokenIssuanceSetFlags(value); - } - /** * Construct an empty instance of {@link MpTokenIssuanceSetFlags}. Transactions with empty flags will not be * serialized with a {@code Flags} field. diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java index 566975e68..2a504f306 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/jackson/modules/MpTokenObjectAmountDeserializer.java @@ -22,7 +22,8 @@ public MpTokenObjectAmountDeserializer() { @Override public MpTokenObjectAmount deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException { - // sfMaximumAmount is an STUInt64s, which in JSON is represented as a hex-encoded String. - return MpTokenObjectAmount.of(UnsignedLong.valueOf(jsonParser.getText(), 16)); + // sfMaximumAmount is an STUInt64, which in JSON is normally represented in base 16, but sfMaximumAmount is + // in base 10 + return MpTokenObjectAmount.of(UnsignedLong.valueOf(jsonParser.getText())); } } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java index 47937e1d3..b36593df8 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAmount.java @@ -10,6 +10,9 @@ import org.immutables.value.Value.Derived; import org.immutables.value.Value.Immutable; +/** + * {@link CurrencyAmount} type for MPT amounts. + */ @Immutable @JsonSerialize(as = ImmutableMpTokenAmount.class) @JsonDeserialize(as = ImmutableMpTokenAmount.class) @@ -29,6 +32,11 @@ static ImmutableMpTokenAmount.Builder builder() { String value(); + /** + * The amount value, as an {@link UnsignedLong}. + * + * @return An {@link UnsignedLong}. + */ @Value.Derived @JsonIgnore default UnsignedLong unsignedLongValue() { From 01fd33e5a310e95d136c3cbbe8f9e5537fb59adc Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 9 Nov 2024 11:02:51 -0500 Subject: [PATCH 08/10] fix transactions and ledger objects --- .../model/ledger/MpTokenIssuanceObject.java | 28 +++++++++---------- .../xrpl4j/model/ledger/MpTokenObject.java | 10 ------- .../model/transactions/MpTokenAuthorize.java | 5 ++-- .../transactions/MpTokenIssuanceCreate.java | 6 ++-- .../transactions/MpTokenIssuanceSet.java | 6 ++-- .../metadata/MetaMpTokenObject.java | 10 ------- 6 files changed, 21 insertions(+), 44 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java index a98f70bed..e6f195532 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java @@ -41,18 +41,28 @@ default LedgerEntryType ledgerEntryType() { @JsonProperty("Issuer") Address issuer(); + /** + * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an + * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence + * number. + * + * @return An {@link UnsignedInteger} representing the account sequence number. + */ + @JsonProperty("Sequence") + UnsignedInteger sequence(); + + @JsonProperty("TransferFee") + TransferFee transferFee(); + @JsonProperty("AssetScale") AssetScale assetScale(); @JsonProperty("MaximumAmount") - MpTokenObjectAmount maximumAmount(); + Optional maximumAmount(); @JsonProperty("OutstandingAmount") MpTokenObjectAmount outstandingAmount(); - @JsonProperty("TransferFee") - TransferFee transferFee(); - @JsonProperty("MPTokenMetadata") Optional mpTokenMetadata(); @@ -72,16 +82,6 @@ default LedgerEntryType ledgerEntryType() { @JsonProperty("PreviousTxnLgrSeq") UnsignedInteger previousTransactionLedgerSequence(); - /** - * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an - * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence - * number. - * - * @return An {@link UnsignedInteger} representing the account sequence number. - */ - @JsonProperty("Sequence") - UnsignedInteger sequence(); - /** * A hint indicating which page of the owner directory links to this object, in case the directory consists of * multiple pages. diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java index 6de20cd1a..42a3eacb8 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenObject.java @@ -65,16 +65,6 @@ default LedgerEntryType ledgerEntryType() { @JsonProperty("PreviousTxnLgrSeq") UnsignedInteger previousTransactionLedgerSequence(); - /** - * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an - * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence - * number. - * - * @return An {@link UnsignedInteger} representing the account sequence number. - */ - @JsonProperty("Sequence") - UnsignedInteger sequence(); - /** * A hint indicating which page of the owner directory links to this object, in case the directory consists of * multiple pages. diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java index 6ae9018fb..beec024f1 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenAuthorize.java @@ -6,7 +6,6 @@ import org.immutables.value.Value; import org.immutables.value.Value.Immutable; import org.xrpl.xrpl4j.model.flags.MpTokenAuthorizeFlags; -import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceSetFlags; import java.util.Optional; @@ -33,7 +32,7 @@ default MpTokenAuthorizeFlags flags() { @JsonProperty("MPTokenIssuanceID") MpTokenIssuanceId mpTokenIssuanceId(); - @JsonProperty("MPTokenHolder") - Optional
mpTokenHolder(); + @JsonProperty("Holder") + Optional
holder(); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java index 8f24ced37..0528fd1fd 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceCreate.java @@ -23,9 +23,6 @@ static ImmutableMpTokenIssuanceCreate.Builder builder() { return ImmutableMpTokenIssuanceCreate.builder(); } - @JsonProperty("AssetScale") - Optional assetScale(); - /** * Set of {@link MpTokenIssuanceCreateFlags}s for this {@link MpTokenIssuanceCreate}. * @@ -37,6 +34,9 @@ default MpTokenIssuanceCreateFlags flags() { return MpTokenIssuanceCreateFlags.empty(); } + @JsonProperty("AssetScale") + Optional assetScale(); + @JsonProperty("TransferFee") Optional transferFee(); diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java index ec823cab7..ef2708b53 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/MpTokenIssuanceSet.java @@ -6,8 +6,6 @@ import org.immutables.value.Value; import org.immutables.value.Value.Immutable; import org.xrpl.xrpl4j.model.flags.MpTokenIssuanceSetFlags; -import org.xrpl.xrpl4j.model.flags.TransactionFlags; -import org.xrpl.xrpl4j.model.transactions.ImmutableMpTokenIssuanceDestroy.Builder; import java.util.Optional; @@ -34,7 +32,7 @@ default MpTokenIssuanceSetFlags flags() { @JsonProperty("MPTokenIssuanceID") MpTokenIssuanceId mpTokenIssuanceId(); - @JsonProperty("MPTokenHolder") - Optional
mpTokenHolder(); + @JsonProperty("Holder") + Optional
holder(); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java index 6cbed0782..e54c82248 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/metadata/MetaMpTokenObject.java @@ -49,16 +49,6 @@ public interface MetaMpTokenObject extends MetaLedgerObject { @JsonProperty("PreviousTxnLgrSeq") Optional previousTransactionLedgerSequence(); - /** - * A 32-bit unsigned integer that is used to ensure issuances from a given sender may only ever exist once, even if an - * issuance is later deleted. Whenever a new issuance is created, this value must match the account's current Sequence - * number. - * - * @return An {@link UnsignedInteger} representing the account sequence number. - */ - @JsonProperty("Sequence") - Optional sequence(); - /** * A hint indicating which page of the owner directory links to this object, in case the directory consists of * multiple pages. From 102d0359e30f9c06ac7a43ae88f123a221e017c2 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 9 Nov 2024 11:29:42 -0500 Subject: [PATCH 09/10] add RPC methods --- .../accounts/AccountObjectsRequestParams.java | 10 ++++- .../ledger/LedgerEntryRequestParams.java | 45 +++++++++++++++++++ .../ledger/MpTokenLedgerEntryParams.java | 29 ++++++++++++ .../model/client/mpt/MptHoldersMpToken.java | 42 +++++++++++++++++ .../client/mpt/MptHoldersRequestParams.java | 39 ++++++++++++++++ .../model/client/mpt/MptHoldersResponse.java | 42 +++++++++++++++++ .../model/ledger/MpTokenIssuanceObject.java | 9 ++++ .../transactions/TransactionMetadata.java | 9 ++++ 8 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/MpTokenLedgerEntryParams.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersMpToken.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersRequestParams.java create mode 100644 xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersResponse.java diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/accounts/AccountObjectsRequestParams.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/accounts/AccountObjectsRequestParams.java index 138cddae1..a0cf6d23e 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/accounts/AccountObjectsRequestParams.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/accounts/AccountObjectsRequestParams.java @@ -152,7 +152,15 @@ enum AccountObjectType { /** * State account object type. */ - STATE("state"); + STATE("state"), + /** + * MPToken Issuance object type. + */ + MPT_ISSUANCE("mpt_issuance"), + /** + * MPToken object type. + */ + MP_TOKEN("mptoken"); private final String value; diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParams.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParams.java index 4a5fb1692..f09031035 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParams.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParams.java @@ -17,6 +17,8 @@ import org.xrpl.xrpl4j.model.ledger.DidObject; import org.xrpl.xrpl4j.model.ledger.EscrowObject; import org.xrpl.xrpl4j.model.ledger.LedgerObject; +import org.xrpl.xrpl4j.model.ledger.MpTokenIssuanceObject; +import org.xrpl.xrpl4j.model.ledger.MpTokenObject; import org.xrpl.xrpl4j.model.ledger.NfTokenPageObject; import org.xrpl.xrpl4j.model.ledger.OfferObject; import org.xrpl.xrpl4j.model.ledger.OracleObject; @@ -25,6 +27,7 @@ import org.xrpl.xrpl4j.model.ledger.TicketObject; import org.xrpl.xrpl4j.model.transactions.Address; import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; import org.xrpl.xrpl4j.model.transactions.XChainBridge; import java.util.Optional; @@ -361,6 +364,42 @@ static LedgerEntryRequestParams oracle( .build(); } + /** + * Construct a {@link LedgerEntryRequestParams} that requests a {@link MpTokenIssuanceObject} ledger entry. + * + * @param issuanceId The {@link MpTokenIssuanceId} of the token. + * @param ledgerSpecifier A {@link LedgerSpecifier} indicating the ledger to query data from. + * + * @return A {@link LedgerEntryRequestParams} for {@link OracleObject}. + */ + static LedgerEntryRequestParams mpTokenIssuance( + MpTokenIssuanceId issuanceId, + LedgerSpecifier ledgerSpecifier + ) { + return ImmutableLedgerEntryRequestParams.builder() + .mptIssuance(issuanceId) + .ledgerSpecifier(ledgerSpecifier) + .build(); + } + + /** + * Construct a {@link LedgerEntryRequestParams} that requests a {@link MpTokenObject} ledger entry. + * + * @param mpToken The {@link MpTokenLedgerEntryParams} specifying the MPToken. + * @param ledgerSpecifier A {@link LedgerSpecifier} indicating the ledger to query data from. + * + * @return A {@link LedgerEntryRequestParams} for {@link OracleObject}. + */ + static LedgerEntryRequestParams mpToken( + MpTokenLedgerEntryParams mpToken, + LedgerSpecifier ledgerSpecifier + ) { + return ImmutableLedgerEntryRequestParams.builder() + .mpToken(mpToken) + .ledgerSpecifier(ledgerSpecifier) + .build(); + } + /** * Specifies the ledger version to request. A ledger version can be specified by ledger hash, numerical ledger index, * or a shortcut value. @@ -494,6 +533,12 @@ default boolean binary() { */ Optional oracle(); + @JsonProperty("mpt_issuance") + Optional mptIssuance(); + + @JsonProperty("mptoken") + Optional mpToken(); + /** * The {@link Class} of {@link T}. This field is helpful when telling Jackson how to deserialize rippled's response to * a {@link T}. diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/MpTokenLedgerEntryParams.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/MpTokenLedgerEntryParams.java new file mode 100644 index 000000000..638ba16d8 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/MpTokenLedgerEntryParams.java @@ -0,0 +1,29 @@ +package org.xrpl.xrpl4j.model.client.ledger; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.transactions.Address; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; + +@Immutable +@JsonSerialize(as = ImmutableMpTokenLedgerEntryParams.class) +@JsonDeserialize(as = ImmutableMpTokenLedgerEntryParams.class) +public interface MpTokenLedgerEntryParams { + + /** + * Construct a {@code MpTokenLedgerEntryParams} builder. + * + * @return An {@link ImmutableMpTokenLedgerEntryParams.Builder}. + */ + static ImmutableMpTokenLedgerEntryParams.Builder builder() { + return ImmutableMpTokenLedgerEntryParams.builder(); + } + + @JsonProperty("mpt_issuance_id") + MpTokenIssuanceId mpTokenIssuanceId(); + + Address account(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersMpToken.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersMpToken.java new file mode 100644 index 000000000..fbd5b1972 --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersMpToken.java @@ -0,0 +1,42 @@ +package org.xrpl.xrpl4j.model.client.mpt; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.flags.MpTokenFlags; +import org.xrpl.xrpl4j.model.transactions.Address; +import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenAmount; +import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMptHoldersMpToken.class) +@JsonDeserialize(as = ImmutableMptHoldersMpToken.class) +public interface MptHoldersMpToken { + + /** + * Construct a {@code MptHoldersMpToken} builder. + * + * @return An {@link ImmutableMptHoldersMpToken.Builder}. + */ + static ImmutableMptHoldersMpToken.Builder builder() { + return ImmutableMptHoldersMpToken.builder(); + } + + Address account(); + + MpTokenFlags flags(); + + @JsonProperty("mpt_amount") + MpTokenObjectAmount mptAmount(); + + @JsonProperty("locked_amount") + Optional lockedAmount(); + + @JsonProperty("mptoken_index") + Hash256 mpTokenIndex(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersRequestParams.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersRequestParams.java new file mode 100644 index 000000000..707dd37ef --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersRequestParams.java @@ -0,0 +1,39 @@ +package org.xrpl.xrpl4j.model.client.mpt; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedInteger; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier; +import org.xrpl.xrpl4j.model.transactions.Marker; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; + +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMptHoldersRequestParams.class) +@JsonDeserialize(as = ImmutableMptHoldersRequestParams.class) +public interface MptHoldersRequestParams { + + /** + * Construct a {@code MptHoldersRequestParams} builder. + * + * @return An {@link ImmutableMptHoldersRequestParams.Builder}. + */ + static ImmutableMptHoldersRequestParams.Builder builder() { + return ImmutableMptHoldersRequestParams.builder(); + } + + @JsonProperty("mpt_issuance_id") + MpTokenIssuanceId mpTokenIssuanceId(); + + @JsonUnwrapped + LedgerSpecifier ledgerSpecifier(); + + Optional marker(); + + Optional limit(); + +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersResponse.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersResponse.java new file mode 100644 index 000000000..300129f9c --- /dev/null +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/mpt/MptHoldersResponse.java @@ -0,0 +1,42 @@ +package org.xrpl.xrpl4j.model.client.mpt; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.google.common.primitives.UnsignedInteger; +import org.immutables.value.Value.Immutable; +import org.xrpl.xrpl4j.model.client.common.LedgerIndex; +import org.xrpl.xrpl4j.model.transactions.Marker; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; + +import java.util.List; +import java.util.Optional; + +@Immutable +@JsonSerialize(as = ImmutableMptHoldersResponse.class) +@JsonDeserialize(as = ImmutableMptHoldersResponse.class) +public interface MptHoldersResponse { + + /** + * Construct a {@code MptHoldersResponse} builder. + * + * @return An {@link ImmutableMptHoldersResponse.Builder}. + */ + static ImmutableMptHoldersResponse.Builder builder() { + return ImmutableMptHoldersResponse.builder(); + } + + @JsonProperty("mpt_issuance_id") + MpTokenIssuanceId mpTokenIssuanceId(); + + @JsonProperty("mptokens") + List mpTokens(); + + Optional marker(); + + Optional limit(); + + // FIXME: Is this always the field, or does clio also return `ledger_hash` and potentially `ledger_current_index`? + @JsonProperty("ledger_index") + LedgerIndex ledgerIndex(); +} diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java index e6f195532..7262df343 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java @@ -10,6 +10,7 @@ import org.xrpl.xrpl4j.model.transactions.Address; import org.xrpl.xrpl4j.model.transactions.AssetScale; import org.xrpl.xrpl4j.model.transactions.Hash256; +import org.xrpl.xrpl4j.model.transactions.MpTokenIssuanceId; import org.xrpl.xrpl4j.model.transactions.MpTokenObjectAmount; import org.xrpl.xrpl4j.model.transactions.TransferFee; @@ -101,4 +102,12 @@ default LedgerEntryType ledgerEntryType() { * @return A {@link Hash256} containing the ID. */ Hash256 index(); + + /** + * The {@link MpTokenIssuanceId} of the issuance. Only present in responses to {@code ledger_data} and + * {@code account_objects} RPC calls. + * + * @return An {@link Optional}<{@link MpTokenIssuanceId}>. + */ + Optional mpTokenIssuanceId(); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java index d815a6f09..5044887ee 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java @@ -95,6 +95,15 @@ static ImmutableTransactionMetadata.Builder builder() { @JsonProperty("nftoken_ids") List nfTokenIds(); + /** + * The {@link MpTokenIssuanceId} of the {@link org.xrpl.xrpl4j.model.ledger.MpTokenIssuanceObject} created + * via an {@link MpTokenIssuanceCreate} transaction. + * + * @return An {@link Optional}<{@link MpTokenIssuanceId}>. + */ + @JsonProperty("mpt_issuance_id") + Optional mpTokenIssuanceId(); + /** * The ID of the offer created by {@link NfTokenCreateOffer} transactions. Only present in metadata for * {@link NfTokenCreateOffer} transactions. From 51ba23ad2dab0eada60edfad1c138e529bdd6d70 Mon Sep 17 00:00:00 2001 From: nkramer44 Date: Sat, 9 Nov 2024 11:31:40 -0500 Subject: [PATCH 10/10] fix checkstyle --- .../org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java | 2 +- .../org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java index 7262df343..0555b1e83 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/MpTokenIssuanceObject.java @@ -107,7 +107,7 @@ default LedgerEntryType ledgerEntryType() { * The {@link MpTokenIssuanceId} of the issuance. Only present in responses to {@code ledger_data} and * {@code account_objects} RPC calls. * - * @return An {@link Optional}<{@link MpTokenIssuanceId}>. + * @return An {@link Optional} {@link MpTokenIssuanceId}. */ Optional mpTokenIssuanceId(); } diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java index 5044887ee..65649af04 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/TransactionMetadata.java @@ -99,7 +99,7 @@ static ImmutableTransactionMetadata.Builder builder() { * The {@link MpTokenIssuanceId} of the {@link org.xrpl.xrpl4j.model.ledger.MpTokenIssuanceObject} created * via an {@link MpTokenIssuanceCreate} transaction. * - * @return An {@link Optional}<{@link MpTokenIssuanceId}>. + * @return An {@link Optional} {@link MpTokenIssuanceId}. */ @JsonProperty("mpt_issuance_id") Optional mpTokenIssuanceId();