Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AMM support #344

Merged
merged 74 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
3c5eca7
add lsfAMM to AccountRoot
nkramer44 Nov 16, 2022
1960147
add AMM object mapping
nkramer44 Nov 17, 2022
c3cca21
add AmmBid transaction type
nkramer44 Nov 17, 2022
53df22a
update definitions.json
nkramer44 Nov 18, 2022
b078439
add AmmCreate transaction
nkramer44 Nov 18, 2022
c4bed00
add AmmDeposit transaction
nkramer44 Nov 18, 2022
c06c248
add AmmVote transaction
nkramer44 Nov 18, 2022
4538d44
add AmmWithdraw transaction
nkramer44 Nov 21, 2022
adca5a3
add amm_info request response objects and XrplClient method.
nkramer44 Nov 21, 2022
6d835a8
add new transactions to SignatureUtils
nkramer44 Nov 28, 2022
812f8f6
checkpoint
nkramer44 Dec 2, 2022
7b6aaff
fix bug in IssueType that prevented decode
nkramer44 Dec 6, 2022
ab9a263
split out AmmInfoResult amm object
nkramer44 Dec 15, 2022
495ca80
write ITs and add different objects for AuctionSlots and AuthAccounts…
nkramer44 Jan 19, 2023
f93e84e
Merge branch 'main' into nk/amm-support
nkramer44 Jan 19, 2023
bdd78e1
fix tests
nkramer44 Jan 19, 2023
6d01ba9
fix checkstyle
nkramer44 Jan 19, 2023
71d687e
Merge branch 'nk/amm-support' of https://github.com/XRPLF/xrpl4j into…
nkramer44 Jan 19, 2023
68128b4
update data-driven-tests to current set from xrpl.js
nkramer44 Jan 19, 2023
b1225af
disable AmmITs
nkramer44 Jan 19, 2023
1c8f5d7
peg ubuntu version to 20.04 so build works
nkramer44 Jan 19, 2023
06be5df
improve test coverage
nkramer44 Jan 19, 2023
d7c181f
add log
nkramer44 Jan 19, 2023
7256e4e
Merge branch 'main' into nk/amm-support
nkramer44 Jan 20, 2023
1c40e12
add log
nkramer44 Jan 20, 2023
06182b6
Merge branch 'nk/amm-support' of https://github.com/XRPLF/xrpl4j into…
nkramer44 Jan 20, 2023
043b53c
remove logs and increase finishAfter time so we don't get tec_NO_PERM…
nkramer44 Jan 20, 2023
2f02504
fix PaymentChannelIT flaky test
nkramer44 Jan 20, 2023
dfbfad7
Merge branch 'main' into nk/amm-support
nkramer44 Jan 20, 2023
51c0fb4
Merge branch 'main' into nk/amm-support
nkramer44 Jan 20, 2023
6d1a221
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Jan 30, 2023
93e7f83
fix build
nkramer44 Jan 30, 2023
3567ffe
fix tests and add AMM transactions to SignatureUtils
nkramer44 Jan 30, 2023
7b3309a
comment out AmmITs again
nkramer44 Jan 30, 2023
23c99b6
Merge branch 'main' into nk/amm-support
nkramer44 Jan 31, 2023
df2fcad
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Jan 31, 2023
18550eb
fix build
nkramer44 Jan 31, 2023
271e903
Merge branch 'main' into nk/amm-support
nkramer44 Feb 1, 2023
df58f30
fix trading fee calculation in IT.
nkramer44 Feb 13, 2023
c11e101
disable tests again
nkramer44 Feb 13, 2023
408dc5a
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Feb 14, 2023
c7deeae
Merge branch 'main' into nk/amm-support
nkramer44 Feb 22, 2023
8fc4ebf
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Jul 5, 2023
b3b6e69
rename Asset to Issue
nkramer44 Jul 5, 2023
b612433
rename Asset to Issue
nkramer44 Jul 5, 2023
46af15c
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Jul 17, 2023
96c1429
update Flags fields in AMM transactions
nkramer44 Jul 17, 2023
100667a
Rename AmmResult.ammAccount to account.
nkramer44 Jul 17, 2023
c3b6d31
Renamed AmmResult to AmmInfo.
nkramer44 Jul 18, 2023
f4d04bf
retype AmmInfoAuctionSlot.expiration as a ZonedDateTime
nkramer44 Jul 18, 2023
bd32fa0
add en_US locale to expiration ZonedDateTime
nkramer44 Jul 18, 2023
50f1e4c
add AMM related transaction metadata mappings and fixtures.
nkramer44 Jul 18, 2023
2b9d113
fix AmmIT
nkramer44 Jul 19, 2023
2e2aa6c
fix checkstyle and update codec fixtures
nkramer44 Jul 19, 2023
41832b7
Merge branch 'main' into nk/amm-support
nkramer44 Jul 19, 2023
0c90c86
add javadoc to AmmDepositFlags and AmmWithdrawFlags explaining why th…
nkramer44 Jul 19, 2023
9e3c562
Merge branch 'nk/amm-support' of https://github.com/XRPLF/xrpl4j into…
nkramer44 Jul 19, 2023
aa73d3d
Merge branch 'main' into nk/amm-support
nkramer44 Aug 3, 2023
efb7638
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Aug 8, 2023
9ddbbdf
fix checkstyle
nkramer44 Aug 8, 2023
a449df5
Merge branch 'main' into nk/amm-support
nkramer44 Aug 15, 2023
a4c7256
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Sep 18, 2023
6e88d6f
Enable AMM amendment in local rippled node and reenable AmmIT.
nkramer44 Sep 18, 2023
c5586af
fix test
nkramer44 Sep 18, 2023
9202aab
rename AmmInfo.account json property to amm_account
nkramer44 Sep 18, 2023
bac0d62
revert rename
nkramer44 Sep 18, 2023
62c66eb
add amm_account option to AmmInfoRequestPArams
nkramer44 Sep 18, 2023
df34891
add AmmDelete transaction
nkramer44 Sep 18, 2023
c1de7aa
checkstyle
nkramer44 Sep 19, 2023
c9d15be
add more coverage
nkramer44 Sep 19, 2023
97aa77d
make all AMM code @Beta
nkramer44 Sep 19, 2023
9a120f8
fix javadoc errors
nkramer44 Sep 19, 2023
58cfec9
Merge branch 'main' of https://github.com/XRPLF/xrpl4j into nk/amm-su…
nkramer44 Sep 20, 2023
804fa58
fix build
nkramer44 Sep 20, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
import org.xrpl.xrpl4j.model.client.accounts.AccountTransactionsResult;
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesRequestParams;
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesResult;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoRequestParams;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoResult;
import org.xrpl.xrpl4j.model.client.channels.ChannelVerifyRequestParams;
import org.xrpl.xrpl4j.model.client.channels.ChannelVerifyResult;
import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
Expand Down Expand Up @@ -762,6 +764,26 @@ public GatewayBalancesResult gatewayBalances(
return jsonRpcClient.send(request, GatewayBalancesResult.class);
}

/**
* Get info about an AMM by making a call to the amm_info rippled RPC method.
*
* @param params The {@link AmmInfoRequestParams} to send in the request.
*
* @return A {@link AmmInfoResult}.
* @throws JsonRpcClientErrorException if {@code jsonRpcClient} throws an error.
*/
@Beta
public AmmInfoResult ammInfo(
AmmInfoRequestParams params
) throws JsonRpcClientErrorException {
JsonRpcRequest request = JsonRpcRequest.builder()
.method(XrplMethods.AMM_INFO)
.addParams(params)
.build();

return jsonRpcClient.send(request, AmmInfoResult.class);
}

public JsonRpcClient getJsonRpcClient() {
return jsonRpcClient;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
import org.xrpl.xrpl4j.model.client.accounts.AccountTransactionsResult;
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesRequestParams;
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesResult;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoRequestParams;
import org.xrpl.xrpl4j.model.client.amm.AmmInfoResult;
import org.xrpl.xrpl4j.model.client.channels.ChannelVerifyRequestParams;
import org.xrpl.xrpl4j.model.client.channels.ChannelVerifyResult;
import org.xrpl.xrpl4j.model.client.common.LedgerIndex;
Expand Down Expand Up @@ -1025,6 +1027,20 @@ public void nftSellOffers() throws JsonRpcClientErrorException {
assertThat(jsonRpcRequestArgumentCaptor.getValue().params().get(0)).isEqualTo(nftSellOffersRequestParams);
}

@Test
void ammInfo() throws JsonRpcClientErrorException {
AmmInfoRequestParams params = mock(AmmInfoRequestParams.class);
JsonRpcRequest expectedRequest = JsonRpcRequest.builder()
.method(XrplMethods.AMM_INFO)
.addParams(params)
.build();
AmmInfoResult mockResult = mock(AmmInfoResult.class);
when(jsonRpcClientMock.send(expectedRequest, AmmInfoResult.class)).thenReturn(mockResult);
AmmInfoResult result = xrplClient.ammInfo(params);

assertThat(result).isEqualTo(mockResult);
}

@Test
void nftInfo() throws JsonRpcClientErrorException {
NftInfoRequestParams params = NftInfoRequestParams.builder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.xrpl.xrpl4j.codec.binary.types;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Preconditions;
import org.immutables.value.Value;

import java.util.Optional;

/**
* JSON mapping object for the Issue serializable type.
*/
@Value.Immutable
@JsonSerialize(as = ImmutableIssue.class)
@JsonDeserialize(as = ImmutableIssue.class)
public interface Issue {

/**
* Construct a {@code Issue} builder.
*
* @return An {@link ImmutableIssue.Builder}.
*/
static ImmutableIssue.Builder builder() {
return ImmutableIssue.builder();
}

/**
* The currency code of the Issue.
*
* @return A {@link JsonNode} containing the currency code.
*/
JsonNode currency();

/**
* The address of the issuer of this currency. Will be empty if {@link #currency()} is XRP.
*
* @return An optionally present {@link JsonNode}.
*/
Optional<JsonNode> issuer();

/**
* Validate that {@link #issuer()} is empty if {@link #currency()} is "XRP".
*/
@Value.Check
default void checkIssuerEmptyForXrp() {
if (currency().asText().equals("XRP")) {
Preconditions.checkState(!issuer().isPresent(), "If Issue is XRP, issuer must be empty.");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.xrpl.xrpl4j.codec.binary.types;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.xrpl.xrpl4j.codec.addresses.UnsignedByteArray;
import org.xrpl.xrpl4j.codec.binary.BinaryCodecObjectMapperFactory;
import org.xrpl.xrpl4j.codec.binary.serdes.BinaryParser;

public class IssueType extends SerializedType<IssueType> {

private static final ObjectMapper objectMapper = BinaryCodecObjectMapperFactory.getObjectMapper();

public IssueType() {
this(UnsignedByteArray.ofSize(20));
}

public IssueType(UnsignedByteArray bytes) {
super(bytes);
}

@Override
public IssueType fromJson(JsonNode node) throws JsonProcessingException {
if (!node.isObject()) {
throw new IllegalArgumentException("node is not an object");

Check warning on line 25 in xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/IssueType.java

View check run for this annotation

Codecov / codecov/patch

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/codec/binary/types/IssueType.java#L25

Added line #L25 was not covered by tests
}

Issue issue = objectMapper.treeToValue(node, Issue.class);

UnsignedByteArray byteArray = new CurrencyType().fromJson(issue.currency()).value();
issue.issuer().ifPresent(
issuer -> byteArray.append(new AccountIdType().fromJson(issuer).value())
);

return new IssueType(byteArray);
}

@Override
public IssueType fromParser(BinaryParser parser) {
CurrencyType currency = new CurrencyType().fromParser(parser);
if (currency.toJson().asText().equals("XRP")) {
return new IssueType(currency.value());
}
AccountIdType issuer = new AccountIdType().fromParser(parser);
return new IssueType(currency.value().append(issuer.value()));
}

@Override
public JsonNode toJson() {
BinaryParser parser = new BinaryParser(this.toHex());
JsonNode currency = new CurrencyType().fromParser(parser).toJson();

ImmutableIssue.Builder builder = Issue.builder();
builder.currency(currency);
if (!currency.asText().equals("XRP")) {
JsonNode issuer = new AccountIdType().fromParser(parser).toJson();
builder.issuer(issuer);
}

return objectMapper.valueToTree(builder.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -57,6 +57,7 @@ public abstract class SerializedType<T extends SerializedType<T>> {
.put("UInt32", () -> new UInt32Type())
.put("UInt64", () -> new UInt64Type())
.put("Vector256", () -> new Vector256Type())
.put("Issue", () -> new IssueType())
.build();
private final UnsignedByteArray bytes;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,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.CheckCancel;
import org.xrpl.xrpl4j.model.transactions.CheckCash;
import org.xrpl.xrpl4j.model.transactions.CheckCreate;
Expand Down Expand Up @@ -276,6 +282,30 @@ public <T extends Transaction> SingleSignedTransaction<T> addSignatureToTransact
transactionWithSignature = Clawback.builder().from((Clawback) transaction)
.transactionSignature(signature)
.build();
} else if (AmmBid.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignature = AmmBid.builder().from((AmmBid) transaction)
.transactionSignature(signature)
.build();
} else if (AmmCreate.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignature = AmmCreate.builder().from((AmmCreate) transaction)
.transactionSignature(signature)
.build();
} else if (AmmDeposit.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignature = AmmDeposit.builder().from((AmmDeposit) transaction)
.transactionSignature(signature)
.build();
} else if (AmmVote.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignature = AmmVote.builder().from((AmmVote) transaction)
.transactionSignature(signature)
.build();
} else if (AmmWithdraw.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignature = AmmWithdraw.builder().from((AmmWithdraw) transaction)
.transactionSignature(signature)
.build();
} else if (AmmDelete.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignature = AmmDelete.builder().from((AmmDelete) 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.");
Expand Down Expand Up @@ -414,6 +444,30 @@ public <T extends Transaction> T addMultiSignaturesToTransaction(T transaction,
transactionWithSignatures = Clawback.builder().from((Clawback) transaction)
.signers(signers)
.build();
} else if (AmmBid.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignatures = AmmBid.builder().from((AmmBid) transaction)
.signers(signers)
.build();
} else if (AmmCreate.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignatures = AmmCreate.builder().from((AmmCreate) transaction)
.signers(signers)
.build();
} else if (AmmDeposit.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignatures = AmmDeposit.builder().from((AmmDeposit) transaction)
.signers(signers)
.build();
} else if (AmmVote.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignatures = AmmVote.builder().from((AmmVote) transaction)
.signers(signers)
.build();
} else if (AmmWithdraw.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignatures = AmmWithdraw.builder().from((AmmWithdraw) transaction)
.signers(signers)
.build();
} else if (AmmDelete.class.isAssignableFrom(transaction.getClass())) {
transactionWithSignatures = AmmDelete.builder().from((AmmDelete) 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.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -20,6 +20,8 @@
* =========================LICENSE_END==================================
*/

import com.google.common.annotations.Beta;

/**
* A definition class for all rippled method name constants.
*/
Expand Down Expand Up @@ -176,6 +178,12 @@ public class XrplMethods {
*/
public static final String RIPPLE_PATH_FIND = "ripple_path_find";

/**
* Constant for the <a href="https://xrpl.org/amm_info.html">ripple_path_find</a> rippled API method.
*/
@Beta
public static final String AMM_INFO = "amm_info";

// Payment Channel methods
/**
* Constant for the <a href="https://xrpl.org/channel_authorize.html">channel_authorize</a> rippled API method.
Expand Down
Loading
Loading