Skip to content

Commit 847b2fa

Browse files
authored
Support frozenBalances in gateway_balances result (#637)
* Support frozenBalances in gateway_balances result
1 parent b15d12d commit 847b2fa

File tree

4 files changed

+129
-10
lines changed

4 files changed

+129
-10
lines changed

.github/workflows/workflow.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ubuntu-latest
1010
steps:
1111
# Checks-out the repository under $GITHUB_WORKSPACE
12-
- uses: actions/checkout@v4
12+
- uses: actions/checkout@v5
1313
# Set up Java 8
1414
- name: Set up JDK 8
1515
uses: actions/setup-java@v4
@@ -20,7 +20,7 @@ jobs:
2020
- name: Build
2121
run: mvn clean install
2222
- name: Upload to Codecov
23-
uses: codecov/codecov-action@v3.1.0
23+
uses: codecov/codecov-action@v5
2424
with:
2525
token: ${{ secrets.CODECOV_TOKEN }}
2626
fail_ci_if_error: true
@@ -29,7 +29,7 @@ jobs:
2929
runs-on: ubuntu-latest
3030
steps:
3131
# Checks-out the repository under $GITHUB_WORKSPACE
32-
- uses: actions/checkout@v4
32+
- uses: actions/checkout@v5
3333
# Set up Java 8
3434
- name: Set up JDK 8
3535
uses: actions/setup-java@v4
@@ -44,7 +44,7 @@ jobs:
4444
runs-on: ubuntu-latest
4545
steps:
4646
# Checks-out the repository under $GITHUB_WORKSPACE
47-
- uses: actions/checkout@v4
47+
- uses: actions/checkout@v5
4848
# Set up Java 8
4949
- name: Set up JDK 8
5050
uses: actions/setup-java@v4
@@ -63,7 +63,7 @@ jobs:
6363
java: [ 11, 16, 17, 21 ]
6464
steps:
6565
# Checks-out the repository under $GITHUB_WORKSPACE
66-
- uses: actions/checkout@v4
66+
- uses: actions/checkout@v5
6767
# Set up Java version
6868
- name: Set up JDK ${{ matrix.java }}
6969
uses: actions/setup-java@v4
@@ -77,7 +77,7 @@ jobs:
7777
build_jdk_temurin_non_us:
7878
runs-on: ubuntu-latest
7979
steps:
80-
- uses: actions/checkout@v4
80+
- uses: actions/checkout@v5
8181
# Set up Temurin 21
8282
- name: Set up Temurin v21
8383
uses: actions/setup-java@v4
@@ -93,7 +93,7 @@ jobs:
9393
runs-on: ubuntu-latest
9494
steps:
9595
# Checks-out the repository under $GITHUB_WORKSPACE
96-
- uses: actions/checkout@v4
96+
- uses: actions/checkout@v5
9797
# Set up Java 17
9898
- name: Set up JDK 21
9999
uses: actions/setup-java@v4
@@ -111,7 +111,7 @@ jobs:
111111
runs-on: ubuntu-latest
112112
steps:
113113
# Checks-out the repository under $GITHUB_WORKSPACE
114-
- uses: actions/checkout@v4
114+
- uses: actions/checkout@v5
115115
# Set up Java 8
116116
- name: Set up JDK 8
117117
uses: actions/setup-java@v4
@@ -126,7 +126,7 @@ jobs:
126126
runs-on: ubuntu-latest
127127
steps:
128128
# Checks-out the repository under $GITHUB_WORKSPACE
129-
- uses: actions/checkout@v4
129+
- uses: actions/checkout@v5
130130
# Set up Java 8
131131
- name: Set up JDK 8
132132
uses: actions/setup-java@v4
@@ -141,7 +141,7 @@ jobs:
141141
runs-on: ubuntu-latest
142142
steps:
143143
# Checks-out the repository under $GITHUB_WORKSPACE
144-
- uses: actions/checkout@v4
144+
- uses: actions/checkout@v5
145145
# Set up Java 8
146146
- name: Set up JDK 8
147147
uses: actions/setup-java@v4

xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/client/accounts/GatewayBalancesResult.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,18 @@ default GatewayBalancesObligations obligations() {
9292
return GatewayBalancesObligations.builder().build();
9393
}
9494

95+
/**
96+
* Amounts issued to addresses where the trustline is frozen. Note that any counterparties to a frozen trustline
97+
* included in {@link GatewayBalancesRequestParams#hotWallets()} are not included in this field's balances.
98+
*
99+
* @return A {@link GatewayBalancesHotWallets}.
100+
*/
101+
@Value.Default
102+
@JsonProperty("frozen_balances")
103+
default GatewayBalancesHotWallets frozenBalances() {
104+
return GatewayBalancesHotWallets.builder().build();
105+
}
106+
95107
/**
96108
* The identifying hash the ledger version that was used when retrieving this data.
97109
*

xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/client/accounts/GatewayBalancesResultTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ public void testDefaults() {
4545
assertThatThrownBy(result::ledgerCurrentIndexSafe).isInstanceOf(IllegalStateException.class);
4646
assertThatThrownBy(result::ledgerHashSafe).isInstanceOf(IllegalStateException.class);
4747
assertThatThrownBy(result::ledgerIndexSafe).isInstanceOf(IllegalStateException.class);
48+
assertThat(result.frozenBalances()).isEqualTo(GatewayBalancesHotWallets.builder().build());
4849
}
4950
}

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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@
3030
import org.junit.jupiter.api.Test;
3131
import org.xrpl.xrpl4j.client.JsonRpcClientErrorException;
3232
import org.xrpl.xrpl4j.crypto.keys.KeyPair;
33+
import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction;
34+
import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult;
3335
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesIssuedCurrencyAmount;
3436
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesRequestParams;
3537
import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesResult;
3638
import org.xrpl.xrpl4j.model.client.accounts.TrustLine;
3739
import org.xrpl.xrpl4j.model.client.common.LedgerSpecifier;
40+
import org.xrpl.xrpl4j.model.client.transactions.SubmitResult;
41+
import org.xrpl.xrpl4j.model.flags.TrustSetFlags;
3842
import org.xrpl.xrpl4j.model.transactions.Address;
3943
import org.xrpl.xrpl4j.model.transactions.IssuedCurrencyAmount;
44+
import org.xrpl.xrpl4j.model.transactions.TransactionResultCodes;
45+
import org.xrpl.xrpl4j.model.transactions.TrustSet;
4046
import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount;
4147

4248
import java.math.BigDecimal;
@@ -114,5 +120,105 @@ public void testGatewayBalances() throws JsonRpcClientErrorException, JsonProces
114120
)
115121
)
116122
);
123+
assertThat(result.frozenBalances().balancesByHolder()).isEmpty();
124+
125+
KeyPair frozenAccountKeyPair = createRandomAccountEd25519();
126+
127+
///////////////////////////
128+
// Create a Trust Line between issuer and frozenAccount
129+
TrustLine frozenTrustLine = createTrustLine(
130+
frozenAccountKeyPair,
131+
IssuedCurrencyAmount.builder()
132+
.issuer(issuerKeyPair.publicKey().deriveAddress())
133+
.currency(xrpl4jCoin)
134+
.value("5000")
135+
.build(),
136+
XrpCurrencyAmount.ofXrp(BigDecimal.valueOf(1))
137+
);
138+
139+
///////////////////////////
140+
// Send some xrpl4jCoin to the frozenAccount
141+
sendIssuedCurrency(
142+
issuerKeyPair,
143+
frozenAccountKeyPair,
144+
IssuedCurrencyAmount.builder()
145+
.issuer(issuerKeyPair.publicKey().deriveAddress())
146+
.currency(xrpl4jCoin)
147+
.value(frozenTrustLine.limitPeer())
148+
.build(),
149+
XrpCurrencyAmount.ofXrp(BigDecimal.valueOf(1))
150+
);
151+
152+
Address frozenAccountAddress = frozenAccountKeyPair.publicKey().deriveAddress();
153+
this.scanForResult(
154+
() -> getValidatedAccountLines(issuerAddress, frozenAccountAddress),
155+
linesResult -> linesResult.lines().stream()
156+
.anyMatch(line -> line.balance().equals("-" + frozenTrustLine.limitPeer()))
157+
);
158+
159+
///////////////////////////
160+
// Freeze the trustline from the issuer's side
161+
AccountInfoResult issuerAccountInfo = this.scanForResult(
162+
() -> this.getValidatedAccountInfo(issuerAddress)
163+
);
164+
165+
TrustSet freezeTrustSet = TrustSet.builder()
166+
.account(issuerAddress)
167+
.fee(XrpCurrencyAmount.ofXrp(BigDecimal.valueOf(1)))
168+
.sequence(issuerAccountInfo.accountData().sequence())
169+
.limitAmount(IssuedCurrencyAmount.builder()
170+
.currency(xrpl4jCoin)
171+
.issuer(frozenAccountAddress)
172+
.value("0")
173+
.build())
174+
.flags(TrustSetFlags.builder().tfSetFreeze().build())
175+
.signingPublicKey(issuerKeyPair.publicKey())
176+
.build();
177+
178+
SingleSignedTransaction<TrustSet> signedFreezeTrustSet = signatureService.sign(
179+
issuerKeyPair.privateKey(),
180+
freezeTrustSet
181+
);
182+
SubmitResult<TrustSet> freezeSubmitResult = xrplClient.submit(signedFreezeTrustSet);
183+
assertThat(freezeSubmitResult.engineResult()).isEqualTo(TransactionResultCodes.TES_SUCCESS);
184+
185+
this.scanForResult(
186+
() -> getValidatedAccountLines(issuerAddress, frozenAccountAddress),
187+
linesResult -> linesResult.lines().stream()
188+
.anyMatch(TrustLine::freeze)
189+
);
190+
191+
///////////////////////////
192+
// Scenario 1: Call gatewayBalances with frozenAccount in hotWallets
193+
// Assert that frozenBalances is empty (frozen accounts in hotWallets are excluded from frozenBalances)
194+
GatewayBalancesResult resultWithFrozenInHotWallets = xrplClient.gatewayBalances(
195+
GatewayBalancesRequestParams.builder()
196+
.account(issuerAddress)
197+
.addHotWallets(frozenAccountAddress)
198+
.ledgerSpecifier(LedgerSpecifier.VALIDATED)
199+
.build()
200+
);
201+
202+
assertThat(resultWithFrozenInHotWallets.frozenBalances().balancesByHolder()).isEmpty();
203+
204+
///////////////////////////
205+
// Scenario 2: Call gatewayBalances without hotWallets
206+
// Assert that frozenBalances has an entry for the frozen account
207+
GatewayBalancesResult resultWithoutHotWallets = xrplClient.gatewayBalances(
208+
GatewayBalancesRequestParams.builder()
209+
.account(issuerAddress)
210+
.ledgerSpecifier(LedgerSpecifier.VALIDATED)
211+
.build()
212+
);
213+
214+
assertThat(resultWithoutHotWallets.frozenBalances().balancesByHolder())
215+
.containsKey(frozenAccountAddress);
216+
assertThat(resultWithoutHotWallets.frozenBalances().balancesByHolder().get(frozenAccountAddress))
217+
.containsExactly(
218+
GatewayBalancesIssuedCurrencyAmount.builder()
219+
.value("5000")
220+
.currency(xrpl4jCoin)
221+
.build()
222+
);
117223
}
118224
}

0 commit comments

Comments
 (0)