diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AmmWithdraw.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AmmWithdraw.java
index 89ad06bec..93f1bd968 100644
--- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AmmWithdraw.java
+++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AmmWithdraw.java
@@ -96,7 +96,7 @@ static ImmutableAmmWithdraw.Builder builder() {
*
* @return An optionally present {@link IssuedCurrencyAmount}.
*/
- @JsonProperty("LPTokensIn")
+ @JsonProperty("LPTokenIn")
Optional lpTokensIn();
}
diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java
index a1a7e7a5b..ad0ff7d33 100644
--- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java
+++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/EscrowFinish.java
@@ -32,6 +32,8 @@
import com.ripple.cryptoconditions.CryptoConditionReader;
import com.ripple.cryptoconditions.CryptoConditionWriter;
import com.ripple.cryptoconditions.Fulfillment;
+import com.ripple.cryptoconditions.PreimageSha256Fulfillment;
+import com.ripple.cryptoconditions.PreimageSha256Fulfillment.AbstractPreimageSha256Fulfillment;
import com.ripple.cryptoconditions.der.DerEncodingException;
import org.immutables.value.Value;
import org.slf4j.Logger;
@@ -41,6 +43,7 @@
import org.xrpl.xrpl4j.model.transactions.AccountSet.AccountSetFlag;
import java.util.Arrays;
+import java.util.Base64;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
@@ -69,25 +72,39 @@ static ImmutableEscrowFinish.Builder builder() {
* transaction increases if it contains a fulfillment. If the transaction contains a fulfillment, the transaction cost
* is 330 drops of XRP plus another 10 drops for every 16 bytes in size of the preimage.
*
- * @param currentLedgerFeeDrops The number of drops that the ledger demands at present.
- * @param fulfillment The {@link Fulfillment} that is being presented to the ledger for computation
- * purposes.
+ * @param currentLedgerBaseFeeDrops The number of drops that the ledger demands at present.
+ * @param fulfillment The {@link Fulfillment} that is being presented to the ledger for computation
+ * purposes.
*
* @return An {@link XrpCurrencyAmount} representing the computed fee.
*
* @see "https://xrpl.org/escrowfinish.html"
*/
- static XrpCurrencyAmount computeFee(final XrpCurrencyAmount currentLedgerFeeDrops, final Fulfillment fulfillment) {
- Objects.requireNonNull(currentLedgerFeeDrops);
+ static XrpCurrencyAmount computeFee(
+ final XrpCurrencyAmount currentLedgerBaseFeeDrops,
+ final Fulfillment> fulfillment
+ ) {
+ Objects.requireNonNull(currentLedgerBaseFeeDrops);
Objects.requireNonNull(fulfillment);
- UnsignedLong newFee =
- currentLedgerFeeDrops.value() // <-- usually 10 drops, per the docs.
- // <-- https://github.com/ripple/rippled/blob/develop/src/ripple/app/tx/impl/Escrow.cpp#L362
- .plus(UnsignedLong.valueOf(320))
- // <-- 10 drops for each additional 16 bytes.
- .plus(UnsignedLong.valueOf(10 * (fulfillment.getDerivedCondition().getCost() / 16)));
- return XrpCurrencyAmount.of(newFee);
+ if (PreimageSha256Fulfillment.class.isAssignableFrom(fulfillment.getClass())) {
+
+ final long fulfillmentByteSize = Base64.getUrlDecoder().decode(
+ ((PreimageSha256Fulfillment) fulfillment).getEncodedPreimage()
+ ).length;
+ // See https://xrpl.org/docs/references/protocol/transactions/types/escrowfinish#escrowfinish-fields for
+ // computing the additional fee for Escrows.
+ // In particular: `extraFee = view.fees().base * (32 + (fb->size() / 16))`
+ // See https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Escrow.cpp#L368
+ final long baseFee = currentLedgerBaseFeeDrops.value().longValue();
+ final long extraFeeDrops = baseFee * (32 + (fulfillmentByteSize / 16));
+ final long totalFeeDrops = baseFee + extraFeeDrops; // <-- Add an extra base fee
+ return XrpCurrencyAmount.of(
+ UnsignedLong.valueOf(totalFeeDrops)
+ );
+ } else {
+ throw new RuntimeException("Only PreimageSha256Fulfillment is supported.");
+ }
}
/**
@@ -144,11 +161,11 @@ default TransactionFlags flags() {
*
* Note that a similar field does not exist on {@link EscrowCreate},
* {@link org.xrpl.xrpl4j.model.ledger.EscrowObject}, or
- * {@link org.xrpl.xrpl4j.model.transactions.metadata.MetaEscrowObject} because {@link EscrowCreate}s with
- * malformed conditions will never be included in a ledger by the XRPL. Because of this fact, an
+ * {@link org.xrpl.xrpl4j.model.transactions.metadata.MetaEscrowObject} because {@link EscrowCreate}s with malformed
+ * conditions will never be included in a ledger by the XRPL. Because of this fact, an
* {@link org.xrpl.xrpl4j.model.ledger.EscrowObject} and
- * {@link org.xrpl.xrpl4j.model.transactions.metadata.MetaEscrowObject} will also never contain a malformed
- * crypto condition.
+ * {@link org.xrpl.xrpl4j.model.transactions.metadata.MetaEscrowObject} will also never contain a malformed crypto
+ * condition.
*
* @return An {@link Optional} {@link String} containing the hex-encoded PREIMAGE-SHA-256 condition.
*/
@@ -191,8 +208,8 @@ default TransactionFlags flags() {
* If {@link #condition()} is present but {@link #conditionRawValue()} is empty, we set
* {@link #conditionRawValue()} to the underlying value of {@link #condition()}.
* If {@link #condition()} is empty and {@link #conditionRawValue()} is present, we will set
- * {@link #condition()} to the {@link Condition} representing the raw condition value, or leave
- * {@link #condition()} empty if {@link #conditionRawValue()} is a malformed {@link Condition}.
+ * {@link #condition()} to the {@link Condition} representing the raw condition value, or leave {@link #condition()}
+ * empty if {@link #conditionRawValue()} is a malformed {@link Condition}.
*
* @return A normalized {@link EscrowFinish}.
*/
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/BinarySerializationTests.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/BinarySerializationTests.java
index 298e019a6..11df2d770 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/BinarySerializationTests.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/codec/binary/BinarySerializationTests.java
@@ -37,6 +37,8 @@
import org.xrpl.xrpl4j.crypto.keys.PublicKey;
import org.xrpl.xrpl4j.crypto.signing.Signature;
import org.xrpl.xrpl4j.model.flags.AccountSetTransactionFlags;
+import org.xrpl.xrpl4j.model.flags.AmmDepositFlags;
+import org.xrpl.xrpl4j.model.flags.AmmWithdrawFlags;
import org.xrpl.xrpl4j.model.flags.OfferCreateFlags;
import org.xrpl.xrpl4j.model.flags.PaymentChannelClaimFlags;
import org.xrpl.xrpl4j.model.flags.PaymentFlags;
@@ -45,6 +47,8 @@
import org.xrpl.xrpl4j.model.flags.TrustSetFlags;
import org.xrpl.xrpl4j.model.flags.XChainModifyBridgeFlags;
import org.xrpl.xrpl4j.model.jackson.ObjectMapperFactory;
+import org.xrpl.xrpl4j.model.ledger.AuthAccount;
+import org.xrpl.xrpl4j.model.ledger.AuthAccountWrapper;
import org.xrpl.xrpl4j.model.ledger.Issue;
import org.xrpl.xrpl4j.model.ledger.RippleStateObject;
import org.xrpl.xrpl4j.model.ledger.SignerEntry;
@@ -52,6 +56,12 @@
import org.xrpl.xrpl4j.model.transactions.AccountDelete;
import org.xrpl.xrpl4j.model.transactions.AccountSet;
import org.xrpl.xrpl4j.model.transactions.Address;
+import org.xrpl.xrpl4j.model.transactions.AmmBid;
+import org.xrpl.xrpl4j.model.transactions.AmmCreate;
+import org.xrpl.xrpl4j.model.transactions.AmmDelete;
+import org.xrpl.xrpl4j.model.transactions.AmmDeposit;
+import org.xrpl.xrpl4j.model.transactions.AmmVote;
+import org.xrpl.xrpl4j.model.transactions.AmmWithdraw;
import org.xrpl.xrpl4j.model.transactions.AssetPrice;
import org.xrpl.xrpl4j.model.transactions.CheckCancel;
import org.xrpl.xrpl4j.model.transactions.CheckCash;
@@ -67,6 +77,10 @@
import org.xrpl.xrpl4j.model.transactions.EscrowCreate;
import org.xrpl.xrpl4j.model.transactions.EscrowFinish;
import org.xrpl.xrpl4j.model.transactions.Hash256;
+import org.xrpl.xrpl4j.model.transactions.ImmutableAmmBid;
+import org.xrpl.xrpl4j.model.transactions.ImmutableAmmCreate;
+import org.xrpl.xrpl4j.model.transactions.ImmutableAmmDelete;
+import org.xrpl.xrpl4j.model.transactions.ImmutableAmmDeposit;
import org.xrpl.xrpl4j.model.transactions.ImmutableDidDelete;
import org.xrpl.xrpl4j.model.transactions.ImmutableDidSet;
import org.xrpl.xrpl4j.model.transactions.ImmutableOracleDelete;
@@ -92,6 +106,7 @@
import org.xrpl.xrpl4j.model.transactions.PriceDataWrapper;
import org.xrpl.xrpl4j.model.transactions.SetRegularKey;
import org.xrpl.xrpl4j.model.transactions.SignerListSet;
+import org.xrpl.xrpl4j.model.transactions.TradingFee;
import org.xrpl.xrpl4j.model.transactions.Transaction;
import org.xrpl.xrpl4j.model.transactions.TrustSet;
import org.xrpl.xrpl4j.model.transactions.XChainAccountCreateCommit;
@@ -2256,6 +2271,270 @@ void serializeOracleDelete() throws JsonProcessingException {
assertSerializesAndDeserializes(oracleDelete, expectedBinary);
}
+ @Test
+ void serializeAmmWithdraw() throws JsonProcessingException {
+ AmmWithdraw ammWithdraw = AmmWithdraw.builder()
+ .account(Address.of("rpgAg9CgNV9MYUECHTx26h1PEARhreuap7"))
+ .fee(XrpCurrencyAmount.ofDrops(10))
+ .sequence(UnsignedInteger.ONE)
+ .signingPublicKey(
+ PublicKey.fromBase16EncodedPublicKey("02B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC110C234D04AF15F3F654A")
+ )
+ .flags(AmmWithdrawFlags.LP_TOKEN)
+ .asset(Issue.builder()
+ .currency("4755534400000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .asset2(Issue.builder()
+ .currency("524C555344000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .lpTokensIn(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .amount(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .amount2(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .effectivePrice(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .build();
+
+ String expectedBinary = "1200252200010000240000000161D5071AFD498D00000000000000000000000000004C50540000" +
+ "000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C568400000000000000A6BD5071AFD498D0000000000000000000000" +
+ "0000004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5601AD5071AFD498D0000000000000000000000" +
+ "0000004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5601BD5071AFD498D0000000000000000000000" +
+ "0000004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5732102B4A8F64B97151FA303F86417751B7EA5" +
+ "AF1D0014FCC110C234D04AF15F3F654A81141285FD19EDD3FB7146B87251AFB0E17742B37271031847555344000000000000" +
+ "00000000000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C50418524C55534400000000000000000000000000" +
+ "0000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5";
+ assertSerializesAndDeserializes(ammWithdraw, expectedBinary);
+ }
+
+ @Test
+ void serializeAmmBid() throws JsonProcessingException {
+ AmmBid ammBid = AmmBid.builder()
+ .account(Address.of("rpgAg9CgNV9MYUECHTx26h1PEARhreuap7"))
+ .fee(XrpCurrencyAmount.ofDrops(10))
+ .sequence(UnsignedInteger.ONE)
+ .signingPublicKey(
+ PublicKey.fromBase16EncodedPublicKey("02B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC110C234D04AF15F3F654A"))
+ .asset(Issue.builder()
+ .currency("4755534400000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .asset2(Issue.builder()
+ .currency("524C555344000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .bidMin(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .bidMax(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .addAuthAccounts(
+ AuthAccountWrapper.of(AuthAccount.of(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy")))
+ )
+ .build();
+
+ String expectedBinary = "120027240000000168400000000000000A6CD5071AFD498D00000000000000000000000000004C5" +
+ "0540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C56DD5071AFD498D00000000000000000000000000004C5054" +
+ "0000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5732102B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC11" +
+ "0C234D04AF15F3F654A81141285FD19EDD3FB7146B87251AFB0E17742B37271F019E01B8114F78AD4FDA66653106AE45EE5FE" +
+ "683C457E6BA9C5E1F103184755534400000000000000000000000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9" +
+ "C50418524C555344000000000000000000000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5";
+
+ assertSerializesAndDeserializes(ammBid, expectedBinary);
+ }
+
+ @Test
+ void serializeAmmCreate() throws JsonProcessingException {
+ AmmCreate ammCreate = AmmCreate.builder()
+ .account(Address.of("rpgAg9CgNV9MYUECHTx26h1PEARhreuap7"))
+ .fee(XrpCurrencyAmount.ofDrops(10))
+ .sequence(UnsignedInteger.ONE)
+ .signingPublicKey(
+ PublicKey.fromBase16EncodedPublicKey("02B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC110C234D04AF15F3F654A")
+ )
+ .amount(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .amount2(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .tradingFee(TradingFee.of(UnsignedInteger.ONE))
+ .build();
+
+ String expectedBinary = "120023150001240000000161D5071AFD498D00000000000000000000000000004C505400000000" +
+ "00F78AD4FDA66653106AE45EE5FE683C457E6BA9C568400000000000000A6BD5071AFD498D00000000000000000000000000" +
+ "004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5732102B4A8F64B97151FA303F86417751B7EA5AF1D" +
+ "0014FCC110C234D04AF15F3F654A81141285FD19EDD3FB7146B87251AFB0E17742B37271";
+
+ assertSerializesAndDeserializes(ammCreate, expectedBinary);
+ }
+
+ @Test
+ void serializeAmmDelete() throws JsonProcessingException {
+ AmmDelete ammDelete = AmmDelete.builder()
+ .account(Address.of("rpgAg9CgNV9MYUECHTx26h1PEARhreuap7"))
+ .fee(XrpCurrencyAmount.ofDrops(10))
+ .sequence(UnsignedInteger.ONE)
+ .signingPublicKey(
+ PublicKey.fromBase16EncodedPublicKey("02B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC110C234D04AF15F3F654A")
+ )
+ .asset(Issue.builder()
+ .currency("4755534400000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .asset2(Issue.builder()
+ .currency("524C555344000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .build();
+
+ String expectedBinary = "120028240000000168400000000000000A732102B4A8F64B97151FA303F86417751B7EA5AF1" +
+ "D0014FCC110C234D04AF15F3F654A81141285FD19EDD3FB7146B87251AFB0E17742B37271031847555344000000000000" +
+ "00000000000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C50418524C5553440000000000000000000000" +
+ "00000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5";
+
+ assertSerializesAndDeserializes(ammDelete, expectedBinary);
+ }
+
+ @Test
+ void serializeAmmDeposit() throws JsonProcessingException {
+ AmmDeposit ammDeposit = AmmDeposit.builder()
+ .account(Address.of("rpgAg9CgNV9MYUECHTx26h1PEARhreuap7"))
+ .fee(XrpCurrencyAmount.ofDrops(10))
+ .sequence(UnsignedInteger.ONE)
+ .signingPublicKey(
+ PublicKey.fromBase16EncodedPublicKey("02B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC110C234D04AF15F3F654A")
+ )
+ .flags(AmmDepositFlags.SINGLE_ASSET)
+ .asset(Issue.builder()
+ .currency("4755534400000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .asset2(Issue.builder()
+ .currency("524C555344000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .amount(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .amount2(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .effectivePrice(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .lpTokenOut(
+ IssuedCurrencyAmount.builder()
+ .value("200")
+ .currency("LPT")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .tradingFee(TradingFee.ofPercent(BigDecimal.ONE))
+ .build();
+
+ String expectedBinary = "1200241503E82200080000240000000161D5071AFD498D00000000000000000000000000004C50" +
+ "540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C568400000000000000A6BD5071AFD498D0000000000000000" +
+ "0000000000004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C56019D5071AFD498D0000000000000000" +
+ "0000000000004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5601BD5071AFD498D0000000000000000" +
+ "0000000000004C50540000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5732102B4A8F64B97151FA303F8641775" +
+ "1B7EA5AF1D0014FCC110C234D04AF15F3F654A81141285FD19EDD3FB7146B87251AFB0E17742B37271031847555344000000" +
+ "00000000000000000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C50418524C55534400000000000000000000" +
+ "0000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5";
+
+ assertSerializesAndDeserializes(ammDeposit, expectedBinary);
+ }
+
+ @Test
+ void serializeAmmVote() throws JsonProcessingException {
+ AmmVote ammVote = AmmVote.builder()
+ .account(Address.of("rpgAg9CgNV9MYUECHTx26h1PEARhreuap7"))
+ .fee(XrpCurrencyAmount.ofDrops(10))
+ .sequence(UnsignedInteger.ONE)
+ .signingPublicKey(
+ PublicKey.fromBase16EncodedPublicKey("02B4A8F64B97151FA303F86417751B7EA5AF1D0014FCC110C234D04AF15F3F654A")
+ )
+ .asset(Issue.builder()
+ .currency("4755534400000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .asset2(Issue.builder()
+ .currency("524C555344000000000000000000000000000000")
+ .issuer(Address.of("rPZtDb6ZHtfYzMmzyUGvehoi2vYhrNAPhy"))
+ .build()
+ )
+ .tradingFee(TradingFee.ofPercent(BigDecimal.ONE))
+ .build();
+
+ String expectedBinary = "1200261503E8240000000168400000000000000A732102B4A8F64B97151FA303F86417751B7" +
+ "EA5AF1D0014FCC110C234D04AF15F3F654A81141285FD19EDD3FB7146B87251AFB0E17742B37271031847555344000000" +
+ "00000000000000000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C50418524C55534400000000000000000" +
+ "0000000000000F78AD4FDA66653106AE45EE5FE683C457E6BA9C5";
+
+ assertSerializesAndDeserializes(ammVote, expectedBinary);
+ }
+
private void assertSerializesAndDeserializes(
T transaction,
String expectedBinary
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/AmmWithdrawTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/AmmWithdrawTest.java
index 8f89e64ff..d394a00e0 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/AmmWithdrawTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/AmmWithdrawTest.java
@@ -21,7 +21,7 @@ void constructLpTokenWithdrawAndTestJson() throws JSONException, JsonProcessingE
String json = "{\n" +
" \"Account\" : \"rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm\",\n" +
- " \"LPTokensIn\" : " + objectMapper.writeValueAsString(withdraw.lpTokensIn()) + "," +
+ " \"LPTokenIn\" : " + objectMapper.writeValueAsString(withdraw.lpTokensIn()) + "," +
" \"Asset\" : " + objectMapper.writeValueAsString(withdraw.asset()) + "," +
" \"Asset2\" : " + objectMapper.writeValueAsString(withdraw.asset2()) + "," +
" \"Fee\" : \"10\",\n" +
@@ -43,7 +43,7 @@ void constructLpTokenWithdrawWithXrpCurrencyAmountAndTestJson() throws JSONExcep
String json = "{\n" +
" \"Account\" : \"rJVUeRqDFNs2xqA7ncVE6ZoAhPUoaJJSQm\",\n" +
- " \"LPTokensIn\" : \"10\"," +
+ " \"LPTokenIn\" : \"10\"," +
" \"Asset\" : " + objectMapper.writeValueAsString(withdraw.asset()) + "," +
" \"Asset2\" : " + objectMapper.writeValueAsString(withdraw.asset2()) + "," +
" \"Fee\" : \"10\",\n" +
@@ -171,7 +171,7 @@ void constructOneAssetLpTokenAndTestJson() throws JSONException, JsonProcessingE
" \"issuer\" : \"rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd\",\n" +
" \"value\" : \"5\"\n" +
" },\n" +
- " \"LPTokensIn\" : " + objectMapper.writeValueAsString(withdraw.lpTokensIn()) + "," +
+ " \"LPTokenIn\" : " + objectMapper.writeValueAsString(withdraw.lpTokensIn()) + "," +
" \"Asset\" : " + objectMapper.writeValueAsString(withdraw.asset()) + "," +
" \"Asset2\" : " + objectMapper.writeValueAsString(withdraw.asset2()) + "," +
" \"Fee\" : \"10\",\n" +
diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java
index 15358b4c6..42a00da31 100644
--- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java
+++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/EscrowFinishTest.java
@@ -9,9 +9,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,6 +22,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.io.BaseEncoding;
@@ -30,12 +31,16 @@
import com.ripple.cryptoconditions.CryptoConditionReader;
import com.ripple.cryptoconditions.CryptoConditionWriter;
import com.ripple.cryptoconditions.Fulfillment;
+import com.ripple.cryptoconditions.PrefixSha256Fulfillment;
import com.ripple.cryptoconditions.PreimageSha256Condition;
import com.ripple.cryptoconditions.PreimageSha256Fulfillment;
import com.ripple.cryptoconditions.der.DerEncodingException;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.ValueSource;
import org.xrpl.xrpl4j.model.jackson.ObjectMapperFactory;
import org.xrpl.xrpl4j.model.transactions.ImmutableEscrowFinish.Builder;
@@ -86,7 +91,8 @@ public void constructWithNoFulfillmentNoCondition() {
////////////////////////////////
// normalizeCondition tests
- ////////////////////////////////
+
+ /// /////////////////////////////
@Test
void normalizeWithNoConditionNoRawValue() {
@@ -131,7 +137,7 @@ void normalizeWithConditionAndRawValueNonMatching() {
.conditionRawValue("A0258020E3B0C44298FC1C149ABCD4C8996FB92427AE41E4649B934CA495991B7852B855810100")
.build()
).isInstanceOf(IllegalStateException.class)
- .hasMessage("condition and conditionRawValue should be equivalent if both are present.");
+ .hasMessage("condition and conditionRawValue should be equivalent if both are present.");
}
@Test
@@ -178,10 +184,9 @@ void normalizeWithNoConditionAndRawValueForMalformedCondition() {
}
/**
- * This tests the case where conditionRawValue is present and is parseable to a Condition but when the
- * parsed Condition is written to a byte array, the value differs from the conditionRawValue bytes. This
- * can occur if the condition raw value contains a valid condition in the first 32 bytes, but also includes
- * extra bytes afterward.
+ * This tests the case where conditionRawValue is present and is parseable to a Condition but when the parsed
+ * Condition is written to a byte array, the value differs from the conditionRawValue bytes. This can occur if the
+ * condition raw value contains a valid condition in the first 32 bytes, but also includes extra bytes afterward.
*/
@Test
void normalizeConditionWithRawValueThatIsParseableButNotValid() {
@@ -217,7 +222,8 @@ void normalizeWithNoConditionAndRawValueForBadHexLengthCondition() {
////////////////////////////////
// normalizeFulfillment tests
- ////////////////////////////////
+
+ /// /////////////////////////////
@Test
void normalizeWithNoFulfillmentNoRawValue() {
@@ -309,10 +315,10 @@ void normalizeWithNoFulfillmentAndRawValueForMalformedFulfillment() {
}
/**
- * This tests the case where fulfillmentRawValue is present and is parseable to a Fulfillment> but when the
- * parsed Fulfillment is written to a byte array, the value differs from the fulfillmentRawValue bytes. This
- * can occur if the fulfillment raw value contains a valid fulfillment in the first 32 bytes, but also includes
- * extra bytes afterward, such as in transaction 138543329687544CDAFCD3AB0DCBFE9C4F8E710397747BA7155F19426F493C8D.
+ * This tests the case where fulfillmentRawValue is present and is parseable to a Fulfillment> but when the parsed
+ * Fulfillment is written to a byte array, the value differs from the fulfillmentRawValue bytes. This can occur if the
+ * fulfillment raw value contains a valid fulfillment in the first 32 bytes, but also includes extra bytes afterward,
+ * such as in transaction 138543329687544CDAFCD3AB0DCBFE9C4F8E710397747BA7155F19426F493C8D.
*/
@Test
void normalizeFulfillmentWithRawValueThatIsParseableButNotValid() {
@@ -346,8 +352,54 @@ void normalizeWithNoFulfillmentAndRawValueForBadHexLengthFulfillment() {
assertThat(actual.fulfillmentRawValue()).isNotEmpty().get().isEqualTo("123");
}
- @Test
- public void testNormalizeWithVariousFulfillmentSizes() {
+ @ParameterizedTest
+ @CsvSource( {
+ // Simulate 10 drop base fee
+ "0,10,330", // Standard 10 drop fee, plus 320 drops
+ "1,10,330", // Standard 10 drop fee, plus 320 drops
+ "2,10,330", // Standard 10 drop fee, plus 320 drops
+ "15,10,330", // Standard 10 drop fee, plus 320 drops
+ "16,10,340", // Standard 10 drop fee, plus 320 drops + 10 drops for 1 chunk of 16 bytes
+ "17,10,340", // Standard 10 drop fee, plus 320 drops + 10 drops for 1 chunk of 16 bytes
+ "31,10,340", // Standard 10 drop fee, plus 320 drops + 10 drops for 1 chunk of 16 bytes
+ "32,10,350", // Standard 10 drop fee, plus 320 drops + 20 drops for 2 chunks of 16 bytes
+ "33,10,350", // Standard 10 drop fee, plus 320 drops + 20 drops for 2 chunks of 16 bytes
+ // Simulate 100 drop base fee
+ "0,100,3300", // Standard 100 drop fee, plus 3200 drops
+ "1,100,3300", // Standard 100 drop fee, plus 3200 drops
+ "2,100,3300", // Standard 100 drop fee, plus 3200 drops
+ "15,100,3300", // Standard 100 drop fee, plus 3200 drops
+ "16,100,3400", // Standard 100 drop fee, plus 3200 drops + 100 drops for 1 chunk of 16 bytes
+ "17,100,3400", // Standard 100 drop fee, plus 3200 drops + 100 drops for 1 chunk of 16 bytes
+ "31,100,3400", // Standard 100 drop fee, plus 3200 drops + 100 drops for 1 chunk of 16 bytes
+ "32,100,3500", // Standard 100 drop fee, plus 3200 drops + 200 drops for 2 chunks of 16 bytes
+ "33,100,3500", // Standard 100 drop fee, plus 3200 drops + 200 drops for 2 chunks of 16 bytes
+ // Simulate 200 drop base fee
+ "0,200,6600", // Standard 200 drop fee, plus 6400 drops
+ "1,200,6600", // Standard 200 drop fee, plus 6400 drops
+ "2,200,6600", // Standard 200 drop fee, plus 6400 drops
+ "15,200,6600",// Standard 200 drop fee, plus 6400 drops
+ "16,200,6800",// Standard 200 drop fee, plus 6400 drops + 200 drops for 1 chunk of 16 bytes
+ "17,200,6800",// Standard 200 drop fee, plus 6400 drops + 200 drops for 1 chunk of 16 bytes
+ "31,200,6800",// Standard 200 drop fee, plus 6400 drops + 200 drops for 1 chunk of 16 bytes
+ "32,200,7000",// Standard 200 drop fee, plus 6400 drops + 400 drops for 2 chunks of 16 bytes
+ "33,200,7000",// Standard 200 drop fee, plus 6400 drops + 400 drops for 2 chunks of 16 bytes
+ // Simulate 5000 drop base fee
+ "0,5000,165000", // Standard 5000 drop fee, plus 160000 drops
+ "1,5000,165000", // Standard 5000 drop fee, plus 160000 drops
+ "2,5000,165000", // Standard 5000 drop fee, plus 160000 drops
+ "15,5000,165000",// Standard 5000 drop fee, plus 160000 drops
+ "16,5000,170000",// Standard 5000 drop fee, plus 160000 drops + 5000 drops for 1 chunk of 16 bytes
+ "17,5000,170000",// Standard 5000 drop fee, plus 160000 drops + 5000 drops for 1 chunk of 16 bytes
+ "31,5000,170000",// Standard 5000 drop fee, plus 160000 drops + 5000 drops for 1 chunk of 16 bytes
+ "32,5000,175000",// Standard 5000 drop fee, plus 160000 drops + 10000 drops for 2 chunks of 16 bytes
+ "33,5000,175000",// Standard 5000 drop fee, plus 160000 drops + 10000 drops for 2 chunks of 16 bytes
+ })
+ public void testNormalizeWithVariousFulfillmentSizes(int numBytes, int baseFee, int expectedDrops) {
+ /////////////////
+ // Test Normalize
+ /////////////////
+
Builder builder = EscrowFinish.builder()
.fee(XrpCurrencyAmount.ofDrops(1))
.account(Address.of("rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59Ba"))
@@ -355,113 +407,63 @@ public void testNormalizeWithVariousFulfillmentSizes() {
.owner(Address.of("rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH"))
.offerSequence(UnsignedInteger.ZERO);
- // 0 bytes
- Fulfillment fulfillment = PreimageSha256Fulfillment.from(new byte[0]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(330));
-
- // 1 byte
- fulfillment = PreimageSha256Fulfillment.from(new byte[1]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(330));
-
- // 2 byte2
- fulfillment = PreimageSha256Fulfillment.from(new byte[2]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(330));
-
- // 15 bytes
- fulfillment = PreimageSha256Fulfillment.from(new byte[15]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(330));
-
- // 16 bytes
- fulfillment = PreimageSha256Fulfillment.from(new byte[16]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops + 10 drops for 16 bytes
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(340));
-
- // 17 bytes
- fulfillment = PreimageSha256Fulfillment.from(new byte[17]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops + 10 drops for 16 bytes
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(340));
-
- // 31 bytes
- fulfillment = PreimageSha256Fulfillment.from(new byte[31]);
+ Fulfillment> fulfillment = PreimageSha256Fulfillment.from(new byte[numBytes]);
builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
+ builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(baseFee), fulfillment));
builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops + 10 drops for 16 bytes
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(340));
-
- // 32 bytes
- fulfillment = PreimageSha256Fulfillment.from(new byte[32]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops + 20 drops for 32 bytes
+ // Standard fee, plus (32 * base-fee) drops, plus one base-fee for every 16 fulfillment bytes.
// (see https://xrpl.org/transaction-cost.html#fee-levels)
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(350));
+ Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(expectedDrops));
- // 33 bytes
- fulfillment = PreimageSha256Fulfillment.from(new byte[33]);
- builder.fulfillment(fulfillment);
- builder.fee(EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), fulfillment));
- builder.condition(fulfillment.getDerivedCondition());
- // Standard 10 drop fee, plus 320 drops + 20 drops for 32 bytes
- Assertions.assertThat(builder.build().fee()).isEqualTo(XrpCurrencyAmount.ofDrops(350));
+ ///////////////////
+ // Test Compute Fee
+ ///////////////////
+ final XrpCurrencyAmount computedFee = EscrowFinish.computeFee(
+ XrpCurrencyAmount.ofDrops(baseFee), PreimageSha256Fulfillment.from(new byte[numBytes])
+ );
+ assertThat(computedFee).isEqualTo(XrpCurrencyAmount.ofDrops(expectedDrops));
}
@Test
- public void testComputeFee() {
- // 0 bytes
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[0])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(330));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[1])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(330));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[2])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(330));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[15])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(330));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[16])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(340));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[17])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(340));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[31])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(340));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[32])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(350));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[33])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(350));
- assertThat(
- EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), PreimageSha256Fulfillment.from(new byte[64])))
- .isEqualTo(XrpCurrencyAmount.ofDrops(370));
+ public void testComputeFeeWithWrongFulfillment() {
+ //////////////////////
+ // Invalid Fulfillment
+ //////////////////////
+
+ PreimageSha256Fulfillment preimageSha256Fulfillment = PreimageSha256Fulfillment.from(new byte[10]);
+ PrefixSha256Fulfillment prefixFulfillment = PrefixSha256Fulfillment.from(
+ new byte[1], 50, preimageSha256Fulfillment
+ );
+ Exception thrownException = assertThrows(
+ Exception.class, () -> EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), prefixFulfillment)
+ );
+ assertThat(thrownException instanceof RuntimeException).isTrue();
+ assertThat(thrownException.getMessage()).isEqualTo("Only PreimageSha256Fulfillment is supported.");
}
+ @Test
+ public void testComputeFeeWithNullParams() {
+ PreimageSha256Fulfillment preimageSha256Fulfillment = PreimageSha256Fulfillment.from(new byte[10]);
+ PrefixSha256Fulfillment prefixFulfillment = PrefixSha256Fulfillment.from(
+ new byte[1], 50, preimageSha256Fulfillment
+ );
+
+ //////////////////////
+ // Null Base Fee
+ //////////////////////
+ Exception thrownException = assertThrows(
+ Exception.class, () -> EscrowFinish.computeFee(null, prefixFulfillment)
+ );
+ assertThat(thrownException instanceof NullPointerException).isTrue();
+ assertThat(thrownException.getMessage()).isNull();
+
+ //////////////////////
+ // Null Fulfillment
+ //////////////////////
+ thrownException = assertThrows(
+ Exception.class, () -> EscrowFinish.computeFee(XrpCurrencyAmount.ofDrops(10), null)
+ );
+ assertThat(thrownException instanceof NullPointerException).isTrue();
+ assertThat(thrownException.getMessage()).isNull();
+ }
}
diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java
index 5a3c91f4e..e2036c8ab 100644
--- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java
+++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/NfTokenIT.java
@@ -87,7 +87,7 @@ void mint() throws JsonRpcClientErrorException, JsonProcessingException {
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(keyPair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keyPair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.uri(uri)
@@ -174,7 +174,7 @@ void mintFromOtherMinterAccount() throws JsonRpcClientErrorException, JsonProces
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(minterKeyPair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(minterKeyPair.publicKey())
.sequence(minterAccountInfo.accountData().sequence())
.issuer(keyPair.publicKey().deriveAddress())
@@ -215,7 +215,7 @@ void mintAndBurn() throws JsonRpcClientErrorException, JsonProcessingException {
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(keyPair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keyPair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.uri(uri)
@@ -239,7 +239,7 @@ void mintAndBurn() throws JsonRpcClientErrorException, JsonProcessingException {
NfTokenBurn nfTokenBurn = NfTokenBurn.builder()
.nfTokenId(tokenId)
.account(keyPair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keyPair.publicKey())
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.build();
@@ -291,7 +291,7 @@ void mintAndCreateOffer() throws JsonRpcClientErrorException, JsonProcessingExce
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(keyPair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keyPair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.uri(uri)
@@ -317,7 +317,7 @@ void mintAndCreateOffer() throws JsonRpcClientErrorException, JsonProcessingExce
NfTokenCreateOffer nfTokenCreateOffer = NfTokenCreateOffer.builder()
.account(keyPair.publicKey().deriveAddress())
.nfTokenId(tokenId)
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.amount(XrpCurrencyAmount.ofDrops(1000))
.flags(NfTokenCreateOfferFlags.builder()
@@ -382,7 +382,7 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(keypair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keypair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.flags(NfTokenMintFlags.builder()
@@ -416,7 +416,7 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
.account(wallet2.publicKey().deriveAddress())
.owner(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult2.accountData().sequence())
.amount(XrpCurrencyAmount.ofDrops(1000))
.signingPublicKey(wallet2.publicKey())
@@ -470,7 +470,7 @@ void mintAndCreateThenAcceptOffer() throws JsonRpcClientErrorException, JsonProc
NfTokenAcceptOffer nfTokenAcceptOffer = NfTokenAcceptOffer.builder()
.account(keypair.publicKey().deriveAddress())
.buyOffer(nftBuyOffersResult.offers().get(0).nftOfferIndex())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.signingPublicKey(keypair.publicKey())
.build();
@@ -530,7 +530,7 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(keypair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keypair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.uri(uri)
@@ -552,7 +552,7 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
NfTokenCreateOffer nfTokenCreateOffer = NfTokenCreateOffer.builder()
.account(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.amount(XrpCurrencyAmount.ofDrops(1000))
.flags(NfTokenCreateOfferFlags.SELL_NFTOKEN)
@@ -594,7 +594,7 @@ void mintAndCreateOfferThenCancelOffer() throws JsonRpcClientErrorException, Jso
NfTokenCancelOffer nfTokenCancelOffer = NfTokenCancelOffer.builder()
.addTokenOffers(nftSellOffersResult.offers().get(0).nftOfferIndex())
.account(keypair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.valueOf(2)))
.signingPublicKey(keypair.publicKey())
.build();
@@ -643,7 +643,7 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
NfTokenMint nfTokenMint = NfTokenMint.builder()
.tokenTaxon(UnsignedLong.ONE)
.account(keypair.publicKey().deriveAddress())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.signingPublicKey(keypair.publicKey())
.sequence(accountInfoResult.accountData().sequence())
.flags(NfTokenMintFlags.builder()
@@ -669,7 +669,7 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
NfTokenCreateOffer nfTokenCreateSellOffer = NfTokenCreateOffer.builder()
.account(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult.accountData().sequence().plus(UnsignedInteger.ONE))
.amount(XrpCurrencyAmount.ofDrops(1000))
.signingPublicKey(keypair.publicKey())
@@ -719,7 +719,7 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
.account(keypair2.publicKey().deriveAddress())
.owner(keypair.publicKey().deriveAddress())
.nfTokenId(tokenId)
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult2.accountData().sequence())
.amount(XrpCurrencyAmount.ofDrops(1000))
.signingPublicKey(keypair2.publicKey())
@@ -767,7 +767,7 @@ void acceptOfferDirectModeWithBrokerFee() throws JsonRpcClientErrorException, Js
.account(wallet3.publicKey().deriveAddress())
.buyOffer(nftBuyOffersResult.offers().get(0).nftOfferIndex())
.sellOffer(nftSellOffersResult.offers().get(0).nftOfferIndex())
- .fee(XrpCurrencyAmount.ofDrops(50))
+ .fee(FeeUtils.computeNetworkFees(xrplClient.fee()).recommendedFee())
.sequence(accountInfoResult3.accountData().sequence())
.signingPublicKey(wallet3.publicKey())
.build();