Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a1dd179
Upcoming changes to Single Asset Vault (DGE-7974)
cybele-ripple Sep 3, 2026
d44e8f9
Address review of Single Asset Vault changes (DGE-7974)
cybele-ripple Sep 3, 2026
0504c81
Add missing @Override annotation to tfInnerBatchTxn() in Vault flags …
cybele-ripple Sep 4, 2026
53d66bd
Address PR review feedback for Vault flags (DGE-7974)
cybele-ripple Sep 17, 2026
5f48277
Add VaultKind, SubscriptionDate, RedemptionDate to support closed-end…
cybele-ripple Sep 17, 2026
fe777cf
Enable LendingProtocolV1_1 amendment for local rippled test container…
cybele-ripple Sep 17, 2026
96be695
Merge remote-tracking branch 'origin/main' into single-asset-vault
cybele-ripple Sep 22, 2026
09691be
Add remaining LendingProtocolV1_1 protocol surface
cybele-ripple Sep 24, 2026
e37030e
Attribute the vault deposit-block and donate flags to LendingProtocol…
cybele-ripple Sep 24, 2026
61b6380
Merge remote-tracking branch 'origin/main' into single-asset-vault
cybele-ripple Sep 28, 2026
aae84d3
Fix LendingProtocolIT tecNO_PERMISSION failures on LoanSet/LoanBrokerSet
cybele-ripple Sep 28, 2026
2336840
Widen LendingProtocolIT's Vault SubscriptionDate buffer for real netw…
cybele-ripple Sep 28, 2026
e1e1285
Fix scanForResult timeout mismatch after widening SubscriptionDate bu…
cybele-ripple Sep 29, 2026
e933650
Widen awaitLoanPaymentLate's timeout for real-network ledger close pa…
cybele-ripple Sep 29, 2026
73b0bf3
Omit VaultKind.OPEN_ENDED from serialized Vault JSON
cybele-ripple Oct 2, 2026
96efb58
Address remaining PR 832 review feedback: hashCode, unread locals
cybele-ripple Oct 14, 2026
cff3ebd
Merge remote-tracking branch 'origin/main' into single-asset-vault
cybele-ripple Oct 14, 2026
efd6fdb
Merge remote-tracking branch 'origin/main' into single-asset-vault
cybele-ripple Oct 15, 2026
41c8cb4
Remove LendingProtocolV1_2-gated Vault flags from this LP1.1 branch
cybele-ripple Oct 16, 2026
3b4caf3
Restore VaultFlagsTest.java instead of deleting it
cybele-ripple Oct 16, 2026
2cfdbd0
Address PR review feedback for single-asset-vault
cybele-ripple Oct 19, 2026
994e7ff
Add IT coverage for VaultWithdraw CredentialIDs and VaultDelete MemoData
cybele-ripple Oct 20, 2026
aabded6
fix: remove unread local variable in LendingProtocolIT
cybele-ripple Oct 21, 2026
e4fb977
Merge remote-tracking branch 'origin/main' into single-asset-vault
cybele-ripple Oct 21, 2026
1b0fd62
fix: enforce investment-period bounds in VaultCreate.check()
cybele-ripple Oct 21, 2026
16c1398
Merge remote-tracking branch 'origin/main' into single-asset-vault
cybele-ripple Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions V7_MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ Version 7.0.0 introduces several breaking changes:
`counterpartySign()`) now reject a transaction whose `fee()` is still zero.
4. **`MetaMpTokenIssuanceObject.mpTokenMetadata()` type change** — now returns `Optional<MpTokenMetadata>` instead of
`Optional<String>`.
5. **`ValidatedLedger.age()` type change** — now returns `Optional<UnsignedInteger>` instead of `UnsignedInteger`,
5. **`VaultDeposit` and `VaultSet` `flags()` type change** — now return `VaultDepositFlags` and `VaultSetFlags`
respectively instead of `TransactionFlags`, to support the new `tfVaultDonate` flag on `VaultDeposit` and the new
`tfVaultDepositBlock`/`tfVaultDepositUnblock` flags on `VaultSet`. Those flags require the
`LendingProtocolV1_2` amendment, which is not yet available in rippled.
6. **`ValidatedLedger.age()` type change** — now returns `Optional<UnsignedInteger>` instead of `UnsignedInteger`,
since rippled omits this field when it cannot compute a valid age.

## Breaking Changes
Expand Down Expand Up @@ -280,7 +284,28 @@ Optional<MpTokenMetadata> metadata = metaMpTokenIssuanceObject.mpTokenMetadata()
Optional<String> hexString = metadata.map(MpTokenMetadata::value);
```

### 5. `ValidatedLedger.age()` type change
### 5. `VaultDeposit` and `VaultSet` `flags()` type change

The return type of `VaultDeposit.flags()` changed from `TransactionFlags` to `VaultDepositFlags`, and the return type
of `VaultSet.flags()` changed from `TransactionFlags` to `VaultSetFlags`. This supports the new `tfVaultDonate` flag on
`VaultDeposit`, and the new `tfVaultDepositBlock`/`tfVaultDepositUnblock` flags on `VaultSet`.

Note that all three of those flags are gated on the `LendingProtocolV1_2` amendment, which rippled has not shipped
yet. The types are in place now so the narrowing lands once rather than as a second breaking change, but rippled will
reject a transaction carrying any of these flags until that amendment activates.

**Migration:**

```java
// Before (v6.x.x)
TransactionFlags depositFlags = vaultDeposit.flags();

// After (v7.0.0)
VaultDepositFlags depositFlags = vaultDeposit.flags();
boolean donate = depositFlags.tfVaultDonate();
```

### 6. `ValidatedLedger.age()` type change

The return type of `ServerInfo.ValidatedLedger#age()` changed from `UnsignedInteger` to `Optional<UnsignedInteger>`.
rippled omits the `age` field from `closed_ledger` and `validated_ledger` in `server_info` responses when it cannot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ public class VaultCreateFlags extends TransactionFlags {
*/
public static final VaultCreateFlags VAULT_SHARE_NON_TRANSFERABLE = new VaultCreateFlags(0x00020000L);

/**
* Constant {@link VaultCreateFlags} for the {@code tfVaultOwnerCanBlockDeposit} flag. Requires the
* {@code LendingProtocolV1_2} amendment; rippled rejects the flag when that amendment is not enabled.
*
* @see "https://github.com/XRPLF/XRPL-Standards/pull/469"
*/
public static final VaultCreateFlags VAULT_OWNER_CAN_BLOCK_DEPOSIT = new VaultCreateFlags(0x00040000L);

private VaultCreateFlags(long value) {
super(value);
}
Expand Down Expand Up @@ -52,12 +60,14 @@ public static VaultCreateFlags of(long value) {
private static VaultCreateFlags of(
boolean tfFullyCanonicalSig,
boolean tfVaultPrivate,
boolean tfVaultShareNonTransferable
boolean tfVaultShareNonTransferable,
boolean tfVaultOwnerCanBlockDeposit
) {
long value = Flags.of(
tfFullyCanonicalSig ? TransactionFlags.FULLY_CANONICAL_SIG : UNSET,
tfVaultPrivate ? VAULT_PRIVATE : UNSET,
tfVaultShareNonTransferable ? VAULT_SHARE_NON_TRANSFERABLE : UNSET
tfVaultShareNonTransferable ? VAULT_SHARE_NON_TRANSFERABLE : UNSET,
tfVaultOwnerCanBlockDeposit ? VAULT_OWNER_CAN_BLOCK_DEPOSIT : UNSET
).getValue();
return new VaultCreateFlags(value);
}
Expand Down Expand Up @@ -90,13 +100,25 @@ public boolean tfVaultShareNonTransferable() {
return this.isSet(VaultCreateFlags.VAULT_SHARE_NON_TRANSFERABLE);
}

/**
* If enabled, the vault owner may block and unblock deposits into the vault via a
* {@link org.xrpl.xrpl4j.model.transactions.VaultSet} transaction. This flag can only be set when the vault is
* created.
*
* @return {@code true} if {@code tfVaultOwnerCanBlockDeposit} is set, otherwise {@code false}.
*/
public boolean tfVaultOwnerCanBlockDeposit() {
return this.isSet(VaultCreateFlags.VAULT_OWNER_CAN_BLOCK_DEPOSIT);
}

/**
* A builder class for {@link VaultCreateFlags} flags.
*/
public static class Builder {

private boolean tfVaultPrivate = false;
private boolean tfVaultShareNonTransferable = false;
private boolean tfVaultOwnerCanBlockDeposit = false;

/**
* Set {@code tfVaultPrivate} to the given value.
Expand All @@ -122,6 +144,18 @@ public Builder tfVaultShareNonTransferable(boolean tfVaultShareNonTransferable)
return this;
}

/**
* Set {@code tfVaultOwnerCanBlockDeposit} to the given value.
*
* @param tfVaultOwnerCanBlockDeposit A boolean value.
*
* @return The same {@link Builder}.
*/
public Builder tfVaultOwnerCanBlockDeposit(boolean tfVaultOwnerCanBlockDeposit) {
this.tfVaultOwnerCanBlockDeposit = tfVaultOwnerCanBlockDeposit;
return this;
}

/**
* Build a new {@link VaultCreateFlags} from the current boolean values.
*
Expand All @@ -131,7 +165,8 @@ public VaultCreateFlags build() {
return VaultCreateFlags.of(
true,
tfVaultPrivate,
tfVaultShareNonTransferable
tfVaultShareNonTransferable,
tfVaultOwnerCanBlockDeposit
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package org.xrpl.xrpl4j.model.flags;

import com.google.common.annotations.Beta;
import org.xrpl.xrpl4j.model.transactions.VaultDeposit;

/**
* A set of static {@link TransactionFlags} which can be set on {@link VaultDeposit} transactions.
*
* <p>This class will be marked {@link Beta} until the SingleAssetVault amendment is enabled on mainnet. Its API is
* subject to change.</p>
*
* @see "https://github.com/XRPLF/XRPL-Standards/pull/469"
*/
@Beta
public class VaultDepositFlags extends TransactionFlags {
Comment thread
sappenin marked this conversation as resolved.
Outdated

/**
* Constant {@link VaultDepositFlags} for the {@code tfVaultDonate} flag. Requires the
* {@code LendingProtocolV1_2} amendment; rippled rejects the flag when that amendment is not enabled.
*/
public static final VaultDepositFlags VAULT_DONATE = new VaultDepositFlags(0x00010000L);

/**
* Constant {@link VaultDepositFlags} for the {@code tfInnerBatchTxn} flag.
*
* @see "https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0056-batch"
*/
public static final VaultDepositFlags INNER_BATCH_TXN =
new VaultDepositFlags(TransactionFlags.INNER_BATCH_TXN.getValue());

private VaultDepositFlags(long value) {
super(value);
}

private VaultDepositFlags() {
}

/**
* Create a new {@link Builder}.
*
* @return A new {@link Builder}.
*/
public static Builder builder() {
return new Builder();
}

/**
* Construct {@link VaultDepositFlags} with a given value.
*
* @param value The long-number encoded flags value of this {@link VaultDepositFlags}.
*
* @return New {@link VaultDepositFlags}.
*/
public static VaultDepositFlags of(long value) {
return new VaultDepositFlags(value);
}

private static VaultDepositFlags of(
boolean tfFullyCanonicalSig,
boolean tfVaultDonate,
boolean tfInnerBatchTxn
) {
long value = Flags.of(
tfFullyCanonicalSig ? TransactionFlags.FULLY_CANONICAL_SIG : UNSET,
tfVaultDonate ? VAULT_DONATE : UNSET,
tfInnerBatchTxn ? TransactionFlags.INNER_BATCH_TXN : UNSET
).getValue();
return new VaultDepositFlags(value);
}

/**
* Construct an empty instance of {@link VaultDepositFlags}. Transactions with empty flags will not be serialized
* with a {@code Flags} field.
*
* @return An empty {@link VaultDepositFlags}.
*/
public static VaultDepositFlags empty() {
return new VaultDepositFlags();
}

/**
* If enabled, the deposited assets are donated to the vault, meaning the depositor receives no shares in return.
*
* <p>This flag requires the {@code LendingProtocolV1_1} amendment. Only the vault owner may donate, and the vault
* must already have outstanding shares.</p>
*
* @return {@code true} if {@code tfVaultDonate} is set, otherwise {@code false}.
*/
public boolean tfVaultDonate() {
return this.isSet(VaultDepositFlags.VAULT_DONATE);
}

/**
* Whether the {@code tfInnerBatchTxn} flag is set.
*
* @return {@code true} if {@code tfInnerBatchTxn} is set, otherwise {@code false}.
*/
@Override
public boolean tfInnerBatchTxn() {
Comment thread
github-code-quality[bot] marked this conversation as resolved.
Fixed
return this.isSet(VaultDepositFlags.INNER_BATCH_TXN);
}

/**
* A builder class for {@link VaultDepositFlags} flags.
*/
public static class Builder {

private boolean tfVaultDonate = false;
private boolean tfInnerBatchTxn = false;

/**
* Set {@code tfVaultDonate} to the given value.
*
* @param tfVaultDonate A boolean value.
*
* @return The same {@link Builder}.
*/
public Builder tfVaultDonate(boolean tfVaultDonate) {
this.tfVaultDonate = tfVaultDonate;
return this;
}

/**
* Set {@code tfInnerBatchTxn} to the given value.
*
* @param tfInnerBatchTxn A boolean value.
*
* @return The same {@link Builder}.
*/
public Builder tfInnerBatchTxn(boolean tfInnerBatchTxn) {
this.tfInnerBatchTxn = tfInnerBatchTxn;
return this;
}

/**
* Build a new {@link VaultDepositFlags} from the current boolean values.
*
* @return A new {@link VaultDepositFlags}.
*/
public VaultDepositFlags build() {
return VaultDepositFlags.of(true, tfVaultDonate, tfInnerBatchTxn);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ public class VaultFlags extends Flags {
*/
public static final VaultFlags VAULT_PRIVATE = new VaultFlags(0x00010000);

/**
* Constant {@link VaultFlags} for the {@code lsfVaultDepositBlocked} flag. Only ever set on vaults created under
* the {@code LendingProtocolV1_2} amendment.
*
* @see "https://github.com/XRPLF/XRPL-Standards/pull/469"
*/
public static final VaultFlags VAULT_DEPOSIT_BLOCKED = new VaultFlags(0x00020000);

/**
* Constant {@link VaultFlags} for the {@code lsfVaultOwnerCanBlockDeposit} flag. Only ever set on vaults created
* under the {@code LendingProtocolV1_2} amendment.
*
* @see "https://github.com/XRPLF/XRPL-Standards/pull/469"
*/
public static final VaultFlags VAULT_OWNER_CAN_BLOCK_DEPOSIT = new VaultFlags(0x00040000);

/**
* Required-args Constructor.
*
Expand Down Expand Up @@ -50,4 +66,22 @@ public boolean lsfVaultPrivate() {
return this.isSet(VaultFlags.VAULT_PRIVATE);
}

/**
* If set, indicates that deposits into the vault are blocked.
*
* @return {@code true} if {@code lsfVaultDepositBlocked} is set, otherwise {@code false}.
*/
public boolean lsfVaultDepositBlocked() {
return this.isSet(VaultFlags.VAULT_DEPOSIT_BLOCKED);
}

/**
* If set, indicates that the vault owner can block and unblock deposits into the vault.
*
* @return {@code true} if {@code lsfVaultOwnerCanBlockDeposit} is set, otherwise {@code false}.
*/
public boolean lsfVaultOwnerCanBlockDeposit() {
return this.isSet(VaultFlags.VAULT_OWNER_CAN_BLOCK_DEPOSIT);
}

}
Loading
Loading