|
30 | 30 | import org.junit.jupiter.api.Test; |
31 | 31 | import org.xrpl.xrpl4j.client.JsonRpcClientErrorException; |
32 | 32 | import org.xrpl.xrpl4j.crypto.keys.KeyPair; |
| 33 | +import org.xrpl.xrpl4j.crypto.signing.SingleSignedTransaction; |
| 34 | +import org.xrpl.xrpl4j.model.client.accounts.AccountInfoResult; |
33 | 35 | import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesIssuedCurrencyAmount; |
34 | 36 | import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesRequestParams; |
35 | 37 | import org.xrpl.xrpl4j.model.client.accounts.GatewayBalancesResult; |
36 | 38 | import org.xrpl.xrpl4j.model.client.accounts.TrustLine; |
37 | 39 | 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; |
38 | 42 | import org.xrpl.xrpl4j.model.transactions.Address; |
39 | 43 | import org.xrpl.xrpl4j.model.transactions.IssuedCurrencyAmount; |
| 44 | +import org.xrpl.xrpl4j.model.transactions.TransactionResultCodes; |
| 45 | +import org.xrpl.xrpl4j.model.transactions.TrustSet; |
40 | 46 | import org.xrpl.xrpl4j.model.transactions.XrpCurrencyAmount; |
41 | 47 |
|
42 | 48 | import java.math.BigDecimal; |
@@ -114,5 +120,105 @@ public void testGatewayBalances() throws JsonRpcClientErrorException, JsonProces |
114 | 120 | ) |
115 | 121 | ) |
116 | 122 | ); |
| 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 | + ); |
117 | 223 | } |
118 | 224 | } |
0 commit comments