Skip to content

Commit 38c887c

Browse files
committed
added DelegateLedgerEntryParams and related tests, fixed line length issue, added Delegate to LedgerEntryRequestParams and associated tests
1 parent 4844bc4 commit 38c887c

File tree

6 files changed

+248
-2
lines changed

6 files changed

+248
-2
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.xrpl.xrpl4j.model.client.ledger;
2+
3+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
4+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
5+
import com.google.common.annotations.Beta;
6+
import org.immutables.value.Value.Immutable;
7+
import org.xrpl.xrpl4j.model.transactions.Address;
8+
9+
/**
10+
* Parameters that uniquely identify a {@link org.xrpl.xrpl4j.model.ledger.DelegateObject} on ledger that can be
11+
* used in a {@link LedgerEntryRequestParams} to request a {@link org.xrpl.xrpl4j.model.ledger.DelegateObject}.
12+
*
13+
* <p>This class will be marked {@link Beta} until the featurePermissionDelegation amendment is enabled on mainnet.
14+
* Its API is subject to change.</p>
15+
*/
16+
@Immutable
17+
@JsonSerialize(as = ImmutableDelegateLedgerEntryParams.class)
18+
@JsonDeserialize(as = ImmutableDelegateLedgerEntryParams.class)
19+
@Beta
20+
public interface DelegateLedgerEntryParams {
21+
22+
/**
23+
* Construct a {@code DelegateLedgerEntryParams} builder.
24+
*
25+
* @return An {@link ImmutableDelegateLedgerEntryParams.Builder}.
26+
*/
27+
static ImmutableDelegateLedgerEntryParams.Builder builder() {
28+
return ImmutableDelegateLedgerEntryParams.builder();
29+
}
30+
31+
/**
32+
* The account that wants to authorize another account (the delegating account).
33+
*
34+
* @return An {@link Address}.
35+
*/
36+
Address account();
37+
38+
/**
39+
* The authorized account (the delegate).
40+
*
41+
* @return An {@link Address}.
42+
*/
43+
Address authorize();
44+
}
45+

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParams.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.xrpl.xrpl4j.model.ledger.BridgeObject;
1515
import org.xrpl.xrpl4j.model.ledger.CheckObject;
1616
import org.xrpl.xrpl4j.model.ledger.CredentialObject;
17+
import org.xrpl.xrpl4j.model.ledger.DelegateObject;
1718
import org.xrpl.xrpl4j.model.ledger.DepositPreAuthObject;
1819
import org.xrpl.xrpl4j.model.ledger.DidObject;
1920
import org.xrpl.xrpl4j.model.ledger.EscrowObject;
@@ -445,6 +446,25 @@ static LedgerEntryRequestParams<PermissionedDomainObject> permissionedDomain(
445446
.build();
446447
}
447448

449+
/**
450+
* Construct a {@link LedgerEntryRequestParams} that requests a {@link DelegateObject} ledger entry.
451+
*
452+
* @param params The {@link DelegateLedgerEntryParams} that uniquely identify the
453+
* {@link DelegateObject} on ledger.
454+
* @param ledgerSpecifier A {@link LedgerSpecifier} indicating the ledger to query data from.
455+
*
456+
* @return A {@link LedgerEntryRequestParams} for {@link DelegateObject}.
457+
*/
458+
static LedgerEntryRequestParams<DelegateObject> delegate(
459+
DelegateLedgerEntryParams params,
460+
LedgerSpecifier ledgerSpecifier
461+
) {
462+
return ImmutableLedgerEntryRequestParams.<DelegateObject>builder()
463+
.delegate(params)
464+
.ledgerSpecifier(ledgerSpecifier)
465+
.build();
466+
}
467+
448468
/**
449469
* Specifies the ledger version to request. A ledger version can be specified by ledger hash, numerical ledger index,
450470
* or a shortcut value.
@@ -610,6 +630,13 @@ default boolean binary() {
610630
@JsonProperty("permissioned_domain")
611631
Optional<PermissionedDomainLedgerEntryParams> permissionedDomain();
612632

633+
/**
634+
* Look up a {@link org.xrpl.xrpl4j.model.ledger.DelegateObject} by {@link DelegateLedgerEntryParams}.
635+
*
636+
* @return An optionally-present {@link DelegateLedgerEntryParams}.
637+
*/
638+
Optional<DelegateLedgerEntryParams> delegate();
639+
613640
/**
614641
* The {@link Class} of {@link T}. This field is helpful when telling Jackson how to deserialize rippled's response to
615642
* a {@link T}.
@@ -687,6 +714,10 @@ default Class<T> ledgerObjectClass() {
687714
return (Class<T>) PermissionedDomainObject.class;
688715
}
689716

717+
if (delegate().isPresent()) {
718+
return (Class<T>) DelegateObject.class;
719+
}
720+
690721
return (Class<T>) LedgerObject.class;
691722
}
692723
}

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/ledger/LedgerObject.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ enum LedgerEntryType {
168168
/**
169169
* The {@link LedgerEntryType} for {@code Delegate} ledger objects.
170170
*
171-
* <p>This constant will be marked {@link Beta} until the featurePermissionDelegation amendment is enabled on mainnet.
172-
* Its API is subject to change.</p>
171+
* <p>This constant will be marked {@link Beta} until the featurePermissionDelegation amendment is enabled on
172+
* mainnet. Its API is subject to change.</p>
173173
*/
174174
@Beta
175175
DELEGATE("Delegate"),
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.xrpl.xrpl4j.model.client.ledger;
2+
3+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.xrpl.xrpl4j.model.transactions.Address;
7+
8+
public class DelegateLedgerEntryParamsTest {
9+
10+
@Test
11+
public void testDelegateLedgerEntryParams() {
12+
DelegateLedgerEntryParams delegateLedgerEntryParams = DelegateLedgerEntryParams.builder()
13+
.account(Address.of("rN7n7otQDd6FczFgLdlqtyMVrn3HMtthP4"))
14+
.authorize(Address.of("rfmDuhDyLGgx94qiwf3YF8BUV5j6KSvE8"))
15+
.build();
16+
17+
assertThat(delegateLedgerEntryParams.account()).isEqualTo(Address.of("rN7n7otQDd6FczFgLdlqtyMVrn3HMtthP4"));
18+
assertThat(delegateLedgerEntryParams.authorize()).isEqualTo(Address.of("rfmDuhDyLGgx94qiwf3YF8BUV5j6KSvE8"));
19+
}
20+
}
21+

xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/ledger/LedgerEntryRequestParamsTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.xrpl.xrpl4j.model.ledger.BridgeObject;
2121
import org.xrpl.xrpl4j.model.ledger.CheckObject;
2222
import org.xrpl.xrpl4j.model.ledger.CredentialObject;
23+
import org.xrpl.xrpl4j.model.ledger.DelegateObject;
2324
import org.xrpl.xrpl4j.model.ledger.DepositPreAuthObject;
2425
import org.xrpl.xrpl4j.model.ledger.DidObject;
2526
import org.xrpl.xrpl4j.model.ledger.EscrowObject;
@@ -836,4 +837,48 @@ void testPermissionedDomainParams() throws JSONException, JsonProcessingExceptio
836837

837838
assertCanSerializeAndDeserialize(params, json);
838839
}
840+
841+
@Test
842+
void testDelegateParams() throws JSONException, JsonProcessingException {
843+
DelegateLedgerEntryParams delegateParams = DelegateLedgerEntryParams.builder()
844+
.account(Address.of("rN7n7otQDd6FczFgLdlqtyMVrn3HMtthP4"))
845+
.authorize(Address.of("rfmDuhDyLGgx94qiwf3YF8BUV5j6KSvE8"))
846+
.build();
847+
LedgerEntryRequestParams<DelegateObject> params = LedgerEntryRequestParams.delegate(
848+
delegateParams,
849+
LedgerSpecifier.VALIDATED
850+
);
851+
assertThat(params.delegate()).isNotEmpty().get().isEqualTo(delegateParams);
852+
assertThat(params.ledgerObjectClass()).isEqualTo(DelegateObject.class);
853+
854+
assertThat(params.index()).isEmpty();
855+
assertThat(params.accountRoot()).isEmpty();
856+
assertThat(params.amm()).isEmpty();
857+
assertThat(params.offer()).isEmpty();
858+
assertThat(params.rippleState()).isEmpty();
859+
assertThat(params.check()).isEmpty();
860+
assertThat(params.escrow()).isEmpty();
861+
assertThat(params.paymentChannel()).isEmpty();
862+
assertThat(params.ticket()).isEmpty();
863+
assertThat(params.nftPage()).isEmpty();
864+
assertThat(params.depositPreAuth()).isEmpty();
865+
assertThat(params.did()).isEmpty();
866+
assertThat(params.bridgeAccount()).isEmpty();
867+
assertThat(params.bridge()).isEmpty();
868+
assertThat(params.oracle()).isEmpty();
869+
assertThat(params.mptIssuance()).isEmpty();
870+
assertThat(params.mpToken()).isEmpty();
871+
assertThat(params.permissionedDomain()).isEmpty();
872+
873+
String json = "{" +
874+
" \"delegate\": {" +
875+
" \"account\": \"rN7n7otQDd6FczFgLdlqtyMVrn3HMtthP4\"," +
876+
" \"authorize\": \"rfmDuhDyLGgx94qiwf3YF8BUV5j6KSvE8\"" +
877+
" }," +
878+
" \"binary\": false," +
879+
" \"ledger_index\": \"validated\"" +
880+
"}";
881+
882+
assertCanSerializeAndDeserialize(params, json);
883+
}
839884
}

xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/DelegateIT.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,4 +641,108 @@ public void updateDelegationPermissions() throws JsonRpcClientErrorException, Js
641641

642642
logger.info("Delegate object permissions updated successfully");
643643
}
644+
645+
@Test
646+
public void testLedgerEntryDelegate() throws JsonRpcClientErrorException, JsonProcessingException {
647+
/////////////////////////
648+
// Create random delegator and delegate accounts
649+
KeyPair delegatorKeyPair = createRandomAccountEd25519();
650+
KeyPair delegateKeyPair = createRandomAccountEd25519();
651+
652+
AccountInfoResult delegatorAccountInfo = this.scanForResult(
653+
() -> this.getValidatedAccountInfo(delegatorKeyPair.publicKey().deriveAddress())
654+
);
655+
656+
/////////////////////////
657+
// Create a delegation
658+
List<PermissionWrapper> permissions = Arrays.asList(
659+
PermissionWrapper.builder()
660+
.permission(Permission.builder().permissionValue("Payment").build())
661+
.build(),
662+
PermissionWrapper.builder()
663+
.permission(Permission.builder().permissionValue("TrustSet").build())
664+
.build()
665+
);
666+
667+
FeeResult feeResult = xrplClient.fee();
668+
DelegateSet delegateSet = DelegateSet.builder()
669+
.account(delegatorKeyPair.publicKey().deriveAddress())
670+
.fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee())
671+
.sequence(delegatorAccountInfo.accountData().sequence())
672+
.signingPublicKey(delegatorKeyPair.publicKey())
673+
.authorize(delegateKeyPair.publicKey().deriveAddress())
674+
.permissions(permissions)
675+
.networkId(networkId)
676+
.build();
677+
678+
SingleSignedTransaction<DelegateSet> signedDelegateSet = this.signatureService.sign(
679+
delegatorKeyPair.privateKey(), delegateSet
680+
);
681+
682+
SubmitResult<DelegateSet> result = xrplClient.submit(signedDelegateSet);
683+
assertThat(result.engineResult()).isEqualTo("tesSUCCESS");
684+
685+
/////////////////////////
686+
// Wait for the transaction to be validated
687+
this.scanForResult(
688+
() -> this.getValidatedTransaction(result.transactionResult().hash(), DelegateSet.class)
689+
);
690+
691+
/////////////////////////
692+
// Get the Delegate object via account_objects to verify it exists
693+
AccountObjectsResult accountObjects = this.scanForResult(
694+
() -> getValidatedAccountObjects(delegatorKeyPair.publicKey().deriveAddress())
695+
);
696+
697+
Optional<DelegateObject> delegateObjectFromAccountObjects = accountObjects.accountObjects().stream()
698+
.filter(obj -> DelegateObject.class.isAssignableFrom(obj.getClass()))
699+
.map(obj -> (DelegateObject) obj)
700+
.filter(obj -> obj.authorize().equals(delegateKeyPair.publicKey().deriveAddress()))
701+
.findFirst();
702+
703+
assertThat(delegateObjectFromAccountObjects).isPresent();
704+
DelegateObject expectedDelegateObject = delegateObjectFromAccountObjects.get();
705+
706+
/////////////////////////
707+
// Query the Delegate object via ledger_entry using DelegateLedgerEntryParams
708+
org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult<DelegateObject> delegateEntry = xrplClient.ledgerEntry(
709+
org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams.delegate(
710+
org.xrpl.xrpl4j.model.client.ledger.DelegateLedgerEntryParams.builder()
711+
.account(delegatorKeyPair.publicKey().deriveAddress())
712+
.authorize(delegateKeyPair.publicKey().deriveAddress())
713+
.build(),
714+
LedgerSpecifier.VALIDATED
715+
)
716+
);
717+
718+
assertThat(delegateEntry.node()).isEqualTo(expectedDelegateObject);
719+
assertThat(delegateEntry.node().account()).isEqualTo(delegatorKeyPair.publicKey().deriveAddress());
720+
assertThat(delegateEntry.node().authorize()).isEqualTo(delegateKeyPair.publicKey().deriveAddress());
721+
assertThat(delegateEntry.node().permissions()).hasSize(2);
722+
723+
/////////////////////////
724+
// Also query by index to verify both methods return the same object
725+
org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult<DelegateObject> entryByIndex = xrplClient.ledgerEntry(
726+
org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams.index(
727+
expectedDelegateObject.index(),
728+
DelegateObject.class,
729+
LedgerSpecifier.VALIDATED
730+
)
731+
);
732+
733+
assertThat(entryByIndex.node()).isEqualTo(delegateEntry.node());
734+
735+
/////////////////////////
736+
// Query by index without type parameter
737+
org.xrpl.xrpl4j.model.client.ledger.LedgerEntryResult<LedgerObject> entryByIndexUnTyped = xrplClient.ledgerEntry(
738+
org.xrpl.xrpl4j.model.client.ledger.LedgerEntryRequestParams.index(
739+
expectedDelegateObject.index(),
740+
LedgerSpecifier.VALIDATED
741+
)
742+
);
743+
744+
assertThat(entryByIndex.node()).isEqualTo(entryByIndexUnTyped.node());
745+
746+
logger.info("Delegate object successfully queried via ledger_entry");
747+
}
644748
}

0 commit comments

Comments
 (0)