diff --git a/build.gradle.kts b/build.gradle.kts index 7aa11e7441..ba1c766015 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -216,7 +216,7 @@ subprojects { allprojects { group = "org.stellar.anchor-sdk" - version = "3.0.1" + version = "3.0.0" tasks.jar { manifest { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index e58fbbd2fe..d69fc65004 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -17,7 +17,6 @@ dependencies { implementation(libs.apache.commons.lang3) implementation(libs.bcastle) - implementation(libs.bcutil) implementation(libs.commons.beanutils) implementation(libs.commons.codec) implementation(libs.commons.io) diff --git a/core/src/main/java/org/stellar/anchor/auth/Sep10Jwt.java b/core/src/main/java/org/stellar/anchor/auth/Sep10Jwt.java index 83b38d3e1d..c990686c37 100644 --- a/core/src/main/java/org/stellar/anchor/auth/Sep10Jwt.java +++ b/core/src/main/java/org/stellar/anchor/auth/Sep10Jwt.java @@ -9,7 +9,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.stellar.sdk.MuxedAccount; +import org.stellar.sdk.AccountConverter; +import org.stellar.sdk.KeyPair; +import org.stellar.sdk.xdr.MuxedAccount; @Getter @Setter @@ -109,11 +111,13 @@ void updateAccountAndMemo() { this.accountMemo = null; try { - MuxedAccount maybeMuxedAccount = new MuxedAccount(sub); - if (maybeMuxedAccount.getMuxedId() != null) { + MuxedAccount maybeMuxedAccount = AccountConverter.enableMuxed().encode(sub); + MuxedAccount.MuxedAccountMed25519 muxedAccount = maybeMuxedAccount.getMed25519(); + if (muxedAccount != null) { this.muxedAccount = sub; - this.account = maybeMuxedAccount.getAccountId(); - this.muxedAccountId = maybeMuxedAccount.getMuxedId().longValue(); + byte[] pubKeyBytes = muxedAccount.getEd25519().getUint256(); + this.account = KeyPair.fromPublicKey(pubKeyBytes).getAccountId(); + this.muxedAccountId = muxedAccount.getId().getUint64().getNumber().longValue(); } } catch (Exception ignored) { } diff --git a/core/src/main/java/org/stellar/anchor/horizon/Horizon.java b/core/src/main/java/org/stellar/anchor/horizon/Horizon.java index d648264363..d9727f2005 100644 --- a/core/src/main/java/org/stellar/anchor/horizon/Horizon.java +++ b/core/src/main/java/org/stellar/anchor/horizon/Horizon.java @@ -2,18 +2,16 @@ import static org.stellar.anchor.api.asset.AssetInfo.NATIVE_ASSET_CODE; +import java.io.IOException; +import java.util.Arrays; import java.util.List; import lombok.Getter; import org.stellar.anchor.config.AppConfig; import org.stellar.anchor.util.AssetHelper; import org.stellar.sdk.AssetTypeCreditAlphaNum; import org.stellar.sdk.Server; -import org.stellar.sdk.TrustLineAsset; -import org.stellar.sdk.exception.NetworkException; -import org.stellar.sdk.requests.PaymentsRequestBuilder; import org.stellar.sdk.responses.AccountResponse; import org.stellar.sdk.responses.operations.OperationResponse; -import org.stellar.sdk.xdr.AssetType; /** The horizon-server. */ public class Horizon { @@ -32,7 +30,7 @@ public Server getServer() { return this.horizonServer; } - public boolean isTrustlineConfigured(String account, String asset) throws NetworkException { + public boolean isTrustlineConfigured(String account, String asset) throws IOException { String assetCode = AssetHelper.getAssetCode(asset); if (NATIVE_ASSET_CODE.equals(assetCode)) { return true; @@ -40,15 +38,13 @@ public boolean isTrustlineConfigured(String account, String asset) throws Networ String assetIssuer = AssetHelper.getAssetIssuer(asset); AccountResponse accountResponse = getServer().accounts().account(account); - return accountResponse.getBalances().stream() + return Arrays.stream(accountResponse.getBalances()) .anyMatch( balance -> { - TrustLineAsset trustLineAsset = balance.getTrustLineAsset(); - if (trustLineAsset.getAssetType() == AssetType.ASSET_TYPE_CREDIT_ALPHANUM4 - || trustLineAsset.getAssetType() == AssetType.ASSET_TYPE_CREDIT_ALPHANUM12) { + if (balance.getAssetType().equals("credit_alphanum4") + || balance.getAssetType().equals("credit_alphanum12")) { AssetTypeCreditAlphaNum creditAsset = - (AssetTypeCreditAlphaNum) trustLineAsset.getAsset(); - assert creditAsset != null; + (AssetTypeCreditAlphaNum) balance.getAsset().get(); return creditAsset.getCode().equals(assetCode) && creditAsset.getIssuer().equals(assetIssuer); } @@ -56,14 +52,7 @@ public boolean isTrustlineConfigured(String account, String asset) throws Networ }); } - /** - * Get payment operations for a transaction. - * - * @param stellarTxnId the transaction id - * @return the operations - * @throws NetworkException request failed, see {@link PaymentsRequestBuilder#execute()} - */ - public List getStellarTxnOperations(String stellarTxnId) { + public List getStellarTxnOperations(String stellarTxnId) throws IOException { return getServer() .payments() .includeTransactions(true) diff --git a/core/src/main/java/org/stellar/anchor/sep10/Sep10Helper.java b/core/src/main/java/org/stellar/anchor/sep10/Sep10Helper.java index 62c792e255..e4eb73d494 100644 --- a/core/src/main/java/org/stellar/anchor/sep10/Sep10Helper.java +++ b/core/src/main/java/org/stellar/anchor/sep10/Sep10Helper.java @@ -10,6 +10,7 @@ import org.stellar.anchor.api.exception.InvalidConfigException; import org.stellar.anchor.api.exception.SepException; import org.stellar.anchor.util.Sep1Helper; +import org.stellar.sdk.FormatException; import org.stellar.sdk.KeyPair; public class Sep10Helper { @@ -38,7 +39,7 @@ public static String fetchSigningKeyFromClientDomain(String clientDomain, boolea debugF("Validating client_domain signing key: {}", clientSigningKey); KeyPair.fromAccountId(clientSigningKey); return clientSigningKey; - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | FormatException e) { infoF("SIGNING_KEY {} is not a valid Stellar account Id.", clientSigningKey); throw new SepException( String.format("SIGNING_KEY %s is not a valid Stellar account Id.", clientSigningKey)); diff --git a/core/src/main/java/org/stellar/anchor/sep10/Sep10Service.java b/core/src/main/java/org/stellar/anchor/sep10/Sep10Service.java index f8f1c8a4e7..338e9da673 100644 --- a/core/src/main/java/org/stellar/anchor/sep10/Sep10Service.java +++ b/core/src/main/java/org/stellar/anchor/sep10/Sep10Service.java @@ -11,6 +11,7 @@ import io.jsonwebtoken.Jws; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Metrics; +import java.io.IOException; import java.time.Instant; import java.util.Arrays; import java.util.HashSet; @@ -35,10 +36,7 @@ import org.stellar.anchor.util.Log; import org.stellar.sdk.*; import org.stellar.sdk.Sep10Challenge.ChallengeTransaction; -import org.stellar.sdk.exception.InvalidSep10ChallengeException; -import org.stellar.sdk.exception.NetworkException; -import org.stellar.sdk.operations.ManageDataOperation; -import org.stellar.sdk.operations.Operation; +import org.stellar.sdk.requests.ErrorResponse; import org.stellar.sdk.responses.AccountResponse; /** The Sep-10 protocol service. */ @@ -116,7 +114,7 @@ public ChallengeResponse createChallenge( } public ValidationResponse validateChallenge(ValidationRequest request) - throws SepValidationException { + throws IOException, InvalidSep10ChallengeException, SepValidationException { info("Validating SEP-10 challenge."); ChallengeTransaction challenge = parseChallenge(request); @@ -178,7 +176,8 @@ public ChallengeResponse createChallengeResponse( } } - Transaction newChallenge(ChallengeRequest request, String clientSigningKey, Memo memo) { + Transaction newChallenge(ChallengeRequest request, String clientSigningKey, Memo memo) + throws InvalidSep10ChallengeException { KeyPair signer = KeyPair.fromSecretSeed(secretConfig.getSep10SigningSeed()); long now = Instant.now().getEpochSecond(); @@ -381,7 +380,7 @@ void validateAccountFormat(ChallengeRequest request) throws SepException { // Validate account try { KeyPair.fromAccountId(request.getAccount()); - } catch (IllegalArgumentException ex) { + } catch (Exception ex) { infoF("client wallet account ({}) is invalid", request.getAccount()); throw new SepValidationException("Invalid account."); } @@ -389,7 +388,7 @@ void validateAccountFormat(ChallengeRequest request) throws SepException { void validateChallengeRequest( ValidationRequest request, AccountResponse account, String clientDomain) - throws SepValidationException { + throws InvalidSep10ChallengeException, IOException, SepValidationException { // fetch the signers from the transaction Set signers = fetchSigners(account); // the signatures must be greater than the medium threshold of the account. @@ -416,7 +415,7 @@ void validateChallengeRequest( Set fetchSigners(AccountResponse account) { // Find the signers of the client account. - return account.getSigners().stream() + return Arrays.stream(account.getSigners()) .filter(as -> as.getType().equals("ed25519_public_key")) .map(as -> new Sep10Challenge.Signer(as.getKey(), as.getWeight())) .collect(Collectors.toSet()); @@ -424,7 +423,7 @@ Set fetchSigners(AccountResponse account) { AccountResponse fetchAccount( ValidationRequest request, ChallengeTransaction challenge, String clientDomain) - throws SepValidationException { + throws InvalidSep10ChallengeException, IOException, SepValidationException { // Check the client's account AccountResponse account; try { @@ -433,7 +432,7 @@ AccountResponse fetchAccount( traceF("challenge account: {}", account); sep10ChallengeValidatedCounter.increment(); return account; - } catch (NetworkException ex) { + } catch (ErrorResponse | IOException ex) { infoF("Account {} does not exist in the Stellar Network"); // account not found // The client account does not exist, using the client's master key to verify. @@ -495,7 +494,8 @@ String fetchClientDomain(ChallengeTransaction challenge) { return clientDomain; } - ChallengeTransaction parseChallenge(ValidationRequest request) throws SepValidationException { + ChallengeTransaction parseChallenge(ValidationRequest request) + throws IOException, InvalidSep10ChallengeException, SepValidationException { if (request == null || request.getTransaction() == null) { throw new SepValidationException("{transaction} is required."); @@ -554,17 +554,13 @@ private String authUrl() { * @param network The network to connect to for verifying and retrieving. * @return The extracted home domain from the Manage Data operation within the SEP-10 challenge * transaction. + * @throws IOException If read XDR string fails, the exception will be thrown. * @throws SepValidationException If the transaction is not a valid SEP-10 challenge transaction. */ String extractHomeDomainFromChallengeXdr(String challengeXdr, Network network) - throws SepValidationException { - AbstractTransaction parsed; - try { - parsed = Transaction.fromEnvelopeXdr(challengeXdr, network); - } catch (IllegalArgumentException e) { - throw new SepValidationException("Invalid challenge transaction."); - } - + throws IOException, SepValidationException { + AbstractTransaction parsed = + Transaction.fromEnvelopeXdr(AccountConverter.enableMuxed(), challengeXdr, network); if (!(parsed instanceof Transaction)) { throw new SepValidationException("Transaction cannot be a fee bump transaction"); } @@ -607,7 +603,8 @@ public synchronized Transaction newChallenge( TimeBounds timebounds, String clientDomain, String clientSigningKey, - Memo memo) { + Memo memo) + throws InvalidSep10ChallengeException { return Sep10Challenge.newChallenge( signer, network, @@ -625,7 +622,8 @@ public synchronized ChallengeTransaction readChallengeTransaction( String serverAccountId, Network network, String domainName, - String webAuthDomain) { + String webAuthDomain) + throws InvalidSep10ChallengeException, IOException { return Sep10Challenge.readChallengeTransaction( challengeXdr, serverAccountId, network, domainName, webAuthDomain); } @@ -636,7 +634,8 @@ public synchronized void verifyChallengeTransactionSigners( Network network, String domainName, String webAuthDomain, - Set signers) { + Set signers) + throws InvalidSep10ChallengeException, IOException { Sep10Challenge.verifyChallengeTransactionSigners( challengeXdr, serverAccountId, network, domainName, webAuthDomain, signers); } @@ -648,7 +647,8 @@ public synchronized void verifyChallengeTransactionThreshold( String domainName, String webAuthDomain, int threshold, - Set signers) { + Set signers) + throws InvalidSep10ChallengeException, IOException { Sep10Challenge.verifyChallengeTransactionThreshold( challengeXdr, serverAccountId, network, domainName, webAuthDomain, threshold, signers); } diff --git a/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java b/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java index ee91aefc66..ba7d3d8268 100644 --- a/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java +++ b/core/src/main/java/org/stellar/anchor/sep24/Sep24Service.java @@ -188,7 +188,7 @@ public InteractiveTransactionResponse withdraw( try { debugF("checking if withdraw source account:{} is valid", sourceAccount); KeyPair.fromAccountId(sourceAccount); - } catch (IllegalArgumentException ex) { + } catch (Exception ex) { infoF("invalid account format: {}", sourceAccount); throw new SepValidationException(String.format("invalid account: %s", sourceAccount), ex); } @@ -382,7 +382,7 @@ public InteractiveTransactionResponse deposit(Sep10Jwt token, Map val public void validateAccount(String account) throws AnchorException { try { KeyPair.fromAccountId(account); - } catch (IllegalArgumentException ex) { + } catch (RuntimeException ex) { throw new SepValidationException(String.format("invalid account %s", account)); } } diff --git a/core/src/main/java/org/stellar/anchor/util/AssetHelper.java b/core/src/main/java/org/stellar/anchor/util/AssetHelper.java index b61ec66ca4..2aee8029d0 100644 --- a/core/src/main/java/org/stellar/anchor/util/AssetHelper.java +++ b/core/src/main/java/org/stellar/anchor/util/AssetHelper.java @@ -37,7 +37,7 @@ public static boolean isNonNativeAsset(String assetCode, String assetIssuer) { try { KeyPair.fromAccountId(assetIssuer); return true; - } catch (IllegalArgumentException ex) { + } catch (Exception ex) { return false; } } diff --git a/core/src/main/java/org/stellar/anchor/util/AssetValidator.java b/core/src/main/java/org/stellar/anchor/util/AssetValidator.java index 03514e0824..aefdda3f50 100644 --- a/core/src/main/java/org/stellar/anchor/util/AssetValidator.java +++ b/core/src/main/java/org/stellar/anchor/util/AssetValidator.java @@ -132,7 +132,9 @@ static void validateSep38(AssetService assetService, Sep38Info sep38Info, String } } - // Validate country codes + // TODO: Enable validate country codes in version 3.x because 2.x does not conform to the ISO + // country code + /* if (sep38Info.getCountryCodes() != null) { for (String country : sep38Info.getCountryCodes()) { if (!isCountryCodeValid(country)) @@ -140,7 +142,7 @@ static void validateSep38(AssetService assetService, Sep38Info sep38Info, String String.format("Invalid country code %s defined for asset %s.", country, assetId)); } } - + */ if (sep38Info.getBuyDeliveryMethods() != null) { // Validate methods for (DeliveryMethod method : sep38Info.getBuyDeliveryMethods()) { diff --git a/core/src/main/java/org/stellar/anchor/util/SepHelper.java b/core/src/main/java/org/stellar/anchor/util/SepHelper.java index c181cbcfc1..dc80d3e528 100644 --- a/core/src/main/java/org/stellar/anchor/util/SepHelper.java +++ b/core/src/main/java/org/stellar/anchor/util/SepHelper.java @@ -11,9 +11,9 @@ import org.stellar.anchor.api.exception.BadRequestException; import org.stellar.anchor.api.exception.InvalidStellarAccountException; import org.stellar.anchor.api.sep.SepTransactionStatus; +import org.stellar.sdk.AccountConverter; import org.stellar.sdk.KeyPair; -import org.stellar.sdk.MuxedAccount; -import org.stellar.sdk.xdr.MemoType; +import org.stellar.sdk.xdr.*; public class SepHelper { /** @@ -59,11 +59,15 @@ public static String memoTypeString(MemoType memoType) { public static String getAccountMemo(String strAccount) throws InvalidStellarAccountException { String[] tokens = strAccount.split(":"); switch (tokens.length) { - // TODO: Should we add a catch here to throw an InvalidStellarAccountException exception in - // case of invalid address? case 1: + AccountConverter accountConverter; + if (tokens[0].startsWith("G")) { + accountConverter = AccountConverter.disableMuxed(); + } else { + accountConverter = AccountConverter.enableMuxed(); + } // Check if the account is a valid G... or M... - new MuxedAccount(tokens[0]); + accountConverter.encode(tokens[0]); return null; case 2: KeyPair.fromAccountId(tokens[0]); diff --git a/core/src/main/resources/config/anchor-asset-default-values.yaml b/core/src/main/resources/config/anchor-asset-default-values.yaml index 484425fa08..9b55d46de9 100644 --- a/core/src/main/resources/config/anchor-asset-default-values.yaml +++ b/core/src/main/resources/config/anchor-asset-default-values.yaml @@ -142,10 +142,10 @@ items: # - stellar:USDC:GBN4NNCDGJO4XW4KQU3CBIESUJWFVBUZPOKUZHT7W7WRB7CWOA7BXVQF exchangeable_assets: - # The list of the ISO 3166-1 alpha-2 country codes that the asset is available in. + # The list of the country codes that the asset is available in. # Example: - # - US - # - CA + # - USA + # - CAN country_codes: # An array of objects describing the methods a client can use to sell/deliver funds to the anchor. diff --git a/core/src/test/kotlin/org/stellar/anchor/asset/DefaultAssetServiceTest.kt b/core/src/test/kotlin/org/stellar/anchor/asset/DefaultAssetServiceTest.kt index dfd434f9bb..20c601c19b 100644 --- a/core/src/test/kotlin/org/stellar/anchor/asset/DefaultAssetServiceTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/asset/DefaultAssetServiceTest.kt @@ -239,7 +239,7 @@ internal class DefaultAssetServiceTest { "stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP" ], "country_codes": [ - "US" + "USA" ], "sell_delivery_methods": [ { diff --git a/core/src/test/kotlin/org/stellar/anchor/dto/sep38/InfoResponseTest.kt b/core/src/test/kotlin/org/stellar/anchor/dto/sep38/InfoResponseTest.kt index 52daa219ae..6e0870b49d 100644 --- a/core/src/test/kotlin/org/stellar/anchor/dto/sep38/InfoResponseTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/dto/sep38/InfoResponseTest.kt @@ -51,7 +51,7 @@ class InfoResponseTest { val fiatUSD = assetMap["iso4217:USD"] assertNotNull(fiatUSD) - assertEquals(listOf("US"), fiatUSD!!.countryCodes) + assertEquals(listOf("USA"), fiatUSD!!.countryCodes) val wantSellDeliveryMethod = Sep38Info.DeliveryMethod("WIRE", "Send USD directly to the Anchor's bank account.") assertEquals(listOf(wantSellDeliveryMethod), fiatUSD.sellDeliveryMethods) diff --git a/core/src/test/kotlin/org/stellar/anchor/horizon/HorizonTest.kt b/core/src/test/kotlin/org/stellar/anchor/horizon/HorizonTest.kt index f23648b48b..56ac1c302c 100644 --- a/core/src/test/kotlin/org/stellar/anchor/horizon/HorizonTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/horizon/HorizonTest.kt @@ -2,6 +2,7 @@ package org.stellar.anchor.horizon import io.mockk.every import io.mockk.mockk +import java.util.* import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -9,10 +10,8 @@ import org.junit.jupiter.api.Assertions.assertNotNull import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.stellar.anchor.config.AppConfig -import org.stellar.sdk.Asset import org.stellar.sdk.AssetTypeCreditAlphaNum import org.stellar.sdk.Server -import org.stellar.sdk.TrustLineAsset import org.stellar.sdk.requests.AccountsRequestBuilder import org.stellar.sdk.responses.AccountResponse import org.stellar.sdk.responses.AccountResponse.Balance @@ -85,21 +84,20 @@ internal class HorizonTest { every { appConfig.stellarNetworkPassphrase } returns TEST_HORIZON_PASSPHRASE every { server.accounts() } returns accountsRequestBuilder every { accountsRequestBuilder.account(account) } returns accountResponse - - every { asset1.code } returns "USDC" - every { asset1.issuer } returns "issuerAccount1" - every { asset2.code } returns "USDC" - every { asset2.issuer } returns "issuerAccount2" - - every { balance1.trustLineAsset } returns - TrustLineAsset(Asset.createNonNativeAsset(asset1.code, asset1.issuer)) - every { balance2.trustLineAsset } returns - TrustLineAsset(Asset.createNonNativeAsset(asset2.code, asset2.issuer)) - every { accountResponse.balances } returns listOf(balance1, balance2) + every { balance1.getAssetType() } returns "credit_alphanum4" + every { balance1.getAsset() } returns Optional.of(asset1) + every { balance2.getAssetType() } returns "credit_alphanum12" + every { balance2.getAsset() } returns Optional.of(asset2) + every { asset1.getCode() } returns "USDC" + every { asset1.getIssuer() } returns "issuerAccount1" + every { asset2.getCode() } returns "USDC" + every { asset2.getIssuer() } returns "issuerAccount2" + every { accountResponse.getBalances() } returns arrayOf(balance1, balance2) val horizon = mockk() every { horizon.server } returns server every { horizon.isTrustlineConfigured(account, asset) } answers { callOriginal() } + assertTrue(horizon.isTrustlineConfigured(account, asset)) } @@ -114,25 +112,24 @@ internal class HorizonTest { val balance1: Balance = mockk() val balance2: Balance = mockk() val balance3: Balance = mockk() - // val asset1: AssetTypeNative = mockk() + val asset1: AssetTypeCreditAlphaNum = mockk() val asset2: AssetTypeCreditAlphaNum = mockk() val asset3: AssetTypeCreditAlphaNum = mockk() every { server.accounts() } returns accountsRequestBuilder every { accountsRequestBuilder.account(account) } returns accountResponse - - // asset 1 is native asset - every { asset2.code } returns "SRT" - every { asset2.issuer } returns "issuerAccount1" - every { asset3.code } returns "USDC" - every { asset3.issuer } returns "issuerAccount2" - - every { balance1.trustLineAsset } returns TrustLineAsset(Asset.createNativeAsset()) - every { balance2.trustLineAsset } returns - TrustLineAsset(Asset.createNonNativeAsset(asset2.code, asset2.issuer)) - every { balance3.trustLineAsset } returns - TrustLineAsset(Asset.createNonNativeAsset(asset3.code, asset3.issuer)) - - every { accountResponse.balances } returns listOf(balance1, balance2, balance3) + every { balance1.getAssetType() } returns "credit_alphanum8" + every { balance1.getAsset() } returns Optional.of(asset1) + every { balance2.getAssetType() } returns "credit_alphanum4" + every { balance2.getAsset() } returns Optional.of(asset2) + every { balance3.getAssetType() } returns "credit_alphanum4" + every { balance3.getAsset() } returns Optional.of(asset3) + every { asset1.getCode() } returns "USDC" + every { asset1.getIssuer() } returns "issuerAccount1" + every { asset2.getCode() } returns "SRT" + every { asset2.getIssuer() } returns "issuerAccount1" + every { asset3.getCode() } returns "USDC" + every { asset3.getIssuer() } returns "issuerAccount2" + every { accountResponse.getBalances() } returns arrayOf(balance1, balance2, balance3) every { appConfig.horizonUrl } returns TEST_HORIZON_URI every { appConfig.stellarNetworkPassphrase } returns TEST_HORIZON_PASSPHRASE @@ -140,6 +137,7 @@ internal class HorizonTest { val horizon = mockk() every { horizon.server } returns server every { horizon.isTrustlineConfigured(account, asset) } answers { callOriginal() } + assertFalse(horizon.isTrustlineConfigured(account, asset)) } } diff --git a/core/src/test/kotlin/org/stellar/anchor/sep10/Sep10ServiceTest.kt b/core/src/test/kotlin/org/stellar/anchor/sep10/Sep10ServiceTest.kt index ebef7b94de..b71afed85a 100644 --- a/core/src/test/kotlin/org/stellar/anchor/sep10/Sep10ServiceTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/sep10/Sep10ServiceTest.kt @@ -5,8 +5,11 @@ package org.stellar.anchor.sep10 import com.google.common.io.BaseEncoding import com.google.gson.annotations.SerializedName import io.jsonwebtoken.Jwts -import io.mockk.* +import io.mockk.MockKAnnotations +import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.spyk +import io.mockk.verify import java.io.IOException import java.security.SecureRandom import java.time.Instant @@ -61,10 +64,7 @@ import org.stellar.anchor.util.GsonUtils import org.stellar.anchor.util.NetUtil import org.stellar.sdk.* import org.stellar.sdk.Network.* -import org.stellar.sdk.exception.BadRequestException -import org.stellar.sdk.exception.InvalidSep10ChallengeException -import org.stellar.sdk.operations.ManageDataOperation -import org.stellar.sdk.operations.SetOptionsOperation +import org.stellar.sdk.requests.ErrorResponse import org.stellar.sdk.responses.AccountResponse import org.stellar.walletsdk.auth.DefaultAuthHeaderSigner import org.stellar.walletsdk.auth.createAuthSignToken @@ -202,26 +202,20 @@ internal class Sep10ServiceTest { val sourceAccount = Account(serverKP.accountId, -1L) val op1DomainNameMandatory = - ManageDataOperation.builder() - .name("$serverHomeDomain auth") - .value(encodedNonce) - .sourceAccount(clientKP.accountId) + ManageDataOperation.Builder("$serverHomeDomain auth", encodedNonce) + .setSourceAccount(clientKP.accountId) .build() val op2WebAuthDomainMandatory = - ManageDataOperation.builder() - .name("web_auth_domain") - .value(serverWebAuthDomain.toByteArray()) - .sourceAccount(serverKP.accountId) + ManageDataOperation.Builder("web_auth_domain", serverWebAuthDomain.toByteArray()) + .setSourceAccount(serverKP.accountId) .build() val op3clientDomainOptional = - ManageDataOperation.builder() - .name("client_domain") - .value("lobstr.co".toByteArray()) - .sourceAccount(clientDomainKP.accountId) + ManageDataOperation.Builder("client_domain", "lobstr.co".toByteArray()) + .setSourceAccount(clientDomainKP.accountId) .build() val transaction = - TransactionBuilder(sourceAccount, TESTNET) + TransactionBuilder(AccountConverter.enableMuxed(), sourceAccount, TESTNET) .addPreconditions( TransactionPreconditions.builder().timeBounds(TimeBounds.expiresAfter(900)).build() ) @@ -285,26 +279,20 @@ internal class Sep10ServiceTest { val sourceAccount = Account(serverKP.accountId, -1L) val op1DomainNameMandatory = - ManageDataOperation.builder() - .name("$serverHomeDomain auth") - .value(encodedNonce) - .sourceAccount(clientKP.accountId) + ManageDataOperation.Builder("$serverHomeDomain auth", encodedNonce) + .setSourceAccount(clientKP.accountId) .build() val op2WebAuthDomainMandatory = - ManageDataOperation.builder() - .name("web_auth_domain") - .value(serverWebAuthDomain.toByteArray()) - .sourceAccount(serverKP.accountId) + ManageDataOperation.Builder("web_auth_domain", serverWebAuthDomain.toByteArray()) + .setSourceAccount(serverKP.accountId) .build() val op3clientDomainOptional = - ManageDataOperation.builder() - .name("client_domain") - .value("lobstr.co".toByteArray()) - .sourceAccount(clientDomainKP.accountId) + ManageDataOperation.Builder("client_domain", "lobstr.co".toByteArray()) + .setSourceAccount(clientDomainKP.accountId) .build() val transaction = - TransactionBuilder(sourceAccount, TESTNET) + TransactionBuilder(AccountConverter.enableMuxed(), sourceAccount, TESTNET) .addPreconditions( TransactionPreconditions.builder().timeBounds(TimeBounds.expiresAfter(900)).build() ) @@ -372,16 +360,12 @@ internal class Sep10ServiceTest { val vr = ValidationRequest() vr.transaction = createTestChallenge("", TEST_HOME_DOMAIN, false) - val mockSigners = - listOf(TestSigner(clientKeyPair.accountId, "ed25519_public_key", 1, "").toSigner()) - val accountResponse = - mockk { - every { accountId } returns clientKeyPair.accountId - every { sequenceNumber } returns 1 - every { signers } returns mockSigners - every { thresholds.medThreshold } returns 1 - } + val accountResponse = spyk(AccountResponse(clientKeyPair.accountId, 1)) + val signers = + arrayOf(TestSigner(clientKeyPair.accountId, "ed25519_public_key", 1, "").toSigner()) + every { accountResponse.signers } returns signers + every { accountResponse.thresholds.medThreshold } returns 1 every { horizon.server.accounts().account(ofType(String::class)) } returns accountResponse val response = sep10Service.validateChallenge(vr) @@ -392,20 +376,15 @@ internal class Sep10ServiceTest { @Test @LockAndMockStatic([Sep10Challenge::class]) fun `test validate challenge with client domain`() { - val mockSigners = - listOf( + val accountResponse = spyk(AccountResponse(clientKeyPair.accountId, 1)) + val signers = + arrayOf( TestSigner(clientKeyPair.accountId, "ed25519_public_key", 1, "").toSigner(), TestSigner(clientDomainKeyPair.accountId, "ed25519_public_key", 1, "").toSigner() ) - val accountResponse = - mockk { - every { accountId } returns clientKeyPair.accountId - every { sequenceNumber } returns 1 - every { signers } returns mockSigners - every { thresholds.medThreshold } returns 1 - } - + every { accountResponse.signers } returns signers + every { accountResponse.thresholds.medThreshold } returns 1 every { horizon.server.accounts().account(ofType(String::class)) } returns accountResponse val vr = ValidationRequest() @@ -425,7 +404,7 @@ internal class Sep10ServiceTest { // exists every { horizon.server.accounts().account(ofType(String::class)) } answers { - throw BadRequestException(400, "mock error", null, null) + throw ErrorResponse(0, "mock error") } vr.transaction = createTestChallenge(TEST_CLIENT_DOMAIN, TEST_HOME_DOMAIN, false) @@ -439,7 +418,7 @@ internal class Sep10ServiceTest { every { horizon.server.accounts().account(ofType(String::class)) } answers { - throw BadRequestException(400, "mock error", null, null) + throw ErrorResponse(0, "mock error") } sep10Service.validateChallenge(vr) @@ -730,26 +709,20 @@ internal class Sep10ServiceTest { val sourceAccount = Account(serverKP.accountId, -1L) val op1DomainNameMandatory = - ManageDataOperation.builder() - .name("$serverHomeDomain auth") - .value(encodedNonce) - .sourceAccount(clientAddress) + ManageDataOperation.Builder("$serverHomeDomain auth", encodedNonce) + .setSourceAccount(clientAddress) .build() val op2WebAuthDomainMandatory = - ManageDataOperation.builder() - .name("web_auth_domain") - .value(serverWebAuthDomain.toByteArray()) - .sourceAccount(serverKP.accountId) + ManageDataOperation.Builder("web_auth_domain", serverWebAuthDomain.toByteArray()) + .setSourceAccount(serverKP.accountId) .build() val op3clientDomainOptional = - ManageDataOperation.builder() - .name("client_domain") - .value("lobstr.co".toByteArray()) - .sourceAccount(clientDomainKP.accountId) + ManageDataOperation.Builder("client_domain", "lobstr.co".toByteArray()) + .setSourceAccount(clientDomainKP.accountId) .build() val transaction = - TransactionBuilder(sourceAccount, network) + TransactionBuilder(AccountConverter.enableMuxed(), sourceAccount, network) .addPreconditions( TransactionPreconditions.builder().timeBounds(TimeBounds.expiresAfter(900)).build() ) @@ -784,19 +757,18 @@ internal class Sep10ServiceTest { val clientAccount = horizon.server.accounts().account(clientMasterKP.accountId) val multisigTx = - TransactionBuilder(clientAccount, network) + TransactionBuilder(AccountConverter.enableMuxed(), clientAccount, network) .addPreconditions( TransactionPreconditions.builder().timeBounds(TimeBounds.expiresAfter(900)).build() ) .setBaseFee(300) .addOperation( - SetOptionsOperation.builder() - .lowThreshold(20) - .mediumThreshold(20) - .highThreshold(20) - .signer(Signer.ed25519PublicKey(clientSecondaryKP)) - .signerWeight(10) - .masterKeyWeight(10) + SetOptionsOperation.Builder() + .setLowThreshold(20) + .setMediumThreshold(20) + .setHighThreshold(20) + .setSigner(Signer.ed25519PublicKey(clientSecondaryKP), 10) + .setMasterKeyWeight(10) .build() ) .build() diff --git a/core/src/test/kotlin/org/stellar/anchor/sep38/Sep38ServiceTest.kt b/core/src/test/kotlin/org/stellar/anchor/sep38/Sep38ServiceTest.kt index 16097d8c65..3aa3fc28bc 100644 --- a/core/src/test/kotlin/org/stellar/anchor/sep38/Sep38ServiceTest.kt +++ b/core/src/test/kotlin/org/stellar/anchor/sep38/Sep38ServiceTest.kt @@ -120,7 +120,7 @@ class Sep38ServiceTest { val fiatUSD = assetMap[fiatUSD] assertNotNull(fiatUSD) - assertEquals(listOf("US"), fiatUSD!!.countryCodes) + assertEquals(listOf("USA"), fiatUSD!!.countryCodes) val wantSellDeliveryMethod = Sep38Info.DeliveryMethod("WIRE", "Send USD directly to the Anchor's bank account.") assertEquals(listOf(wantSellDeliveryMethod), fiatUSD.sellDeliveryMethods) @@ -236,7 +236,7 @@ class Sep38ServiceTest { .sellAsset(fiatUSD) .buyAsset("stellar:JPYC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5") .sellAmount("100") - .countryCode("US") + .countryCode("USA") .sellDeliveryMethod("WIRE") .build() every { mockRateIntegration.getRate(getRateReq1) } returns @@ -248,7 +248,7 @@ class Sep38ServiceTest { .sellAsset(fiatUSD) .buyAsset(stellarUSDC) .sellAmount("100") - .countryCode("US") + .countryCode("USA") .sellDeliveryMethod("WIRE") .build() every { mockRateIntegration.getRate(getRateReq2) } returns @@ -258,7 +258,7 @@ class Sep38ServiceTest { // test happy path with all the parameters var gotResponse: GetPricesResponse? = null - assertDoesNotThrow { gotResponse = sep38Service.getPrices(fiatUSD, "100", "WIRE", null, "US") } + assertDoesNotThrow { gotResponse = sep38Service.getPrices(fiatUSD, "100", "WIRE", null, "USA") } val wantResponse = GetPricesResponse() wantResponse.addAsset(stellarJPYC, 2, "1.1") wantResponse.addAsset(stellarUSDC, 2, "2.1") @@ -393,13 +393,13 @@ class Sep38ServiceTest { // unsupported country_code getPriceRequestBuilder = getPriceRequestBuilder.buyDeliveryMethod(null) - getPriceRequestBuilder = getPriceRequestBuilder.countryCode("BR") + getPriceRequestBuilder = getPriceRequestBuilder.countryCode("BRA") ex = assertThrows { sep38Service.getPrice(null, getPriceRequestBuilder.build()) } assertInstanceOf(BadRequestException::class.java, ex) assertEquals("Unsupported country code", ex.message) // unsupported (null) context - getPriceRequestBuilder = getPriceRequestBuilder.countryCode("US") + getPriceRequestBuilder = getPriceRequestBuilder.countryCode("USA") ex = assertThrows { sep38Service.getPrice(null, getPriceRequestBuilder.build()) } assertInstanceOf(BadRequestException::class.java, ex) assertEquals("Unsupported context. Should be one of [sep6, sep31].", ex.message) @@ -497,7 +497,7 @@ class Sep38ServiceTest { .sellAsset(fiatUSD) .buyAsset(stellarUSDC) .sellAmount("100") - .countryCode("US") + .countryCode("USA") .sellDeliveryMethod("WIRE") .build() every { mockRateIntegration.getRate(getRateReq) } returns @@ -512,7 +512,7 @@ class Sep38ServiceTest { .sellAmount("100") .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) - .countryCode("US") + .countryCode("USA") .context(SEP6) .build() var gotResponse: GetPriceResponse? = null @@ -537,7 +537,7 @@ class Sep38ServiceTest { .sellAsset(fiatUSD) .buyAsset(stellarUSDC) .buyAmount("100") - .countryCode("US") + .countryCode("USA") .sellDeliveryMethod("WIRE") .build() @@ -553,7 +553,7 @@ class Sep38ServiceTest { .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) .buyAmount("100") - .countryCode("US") + .countryCode("USA") .context(SEP31) .build() var gotResponse: GetPriceResponse? = null @@ -788,7 +788,7 @@ class Sep38ServiceTest { .sellAmount("1.23") .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) - .countryCode("BR") + .countryCode("BRA") .build() ) } @@ -804,7 +804,7 @@ class Sep38ServiceTest { .sellAmount("1.23") .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) - .countryCode("US") + .countryCode("USA") .expireAfter("2022-04-18T23:33:24.629719Z") .build() ) @@ -1063,7 +1063,7 @@ class Sep38ServiceTest { .sellAmount("100") .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) - .countryCode("US") + .countryCode("USA") .expireAfter(now.toString()) .build() ) @@ -1167,7 +1167,7 @@ class Sep38ServiceTest { .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) .buyAmount("100") - .countryCode("US") + .countryCode("USA") .expireAfter(now.toString()) .build() ) @@ -1279,7 +1279,7 @@ class Sep38ServiceTest { .sellDeliveryMethod("WIRE") .buyAssetName(stellarUSDC) .buyAmount(requestBuyAmount) - .countryCode("US") + .countryCode("USA") .expireAfter(now.toString()) .build() ) diff --git a/core/src/test/resources/test_assets.json b/core/src/test/resources/test_assets.json index ea908cd02b..61624d803b 100644 --- a/core/src/test/resources/test_assets.json +++ b/core/src/test/resources/test_assets.json @@ -159,7 +159,7 @@ "stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP" ], "country_codes": [ - "US" + "USA" ], "decimals": 4, "sell_delivery_methods": [ diff --git a/core/src/test/resources/test_assets.yaml b/core/src/test/resources/test_assets.yaml index 60cf4795b7..eb5f805148 100644 --- a/core/src/test/resources/test_assets.yaml +++ b/core/src/test/resources/test_assets.yaml @@ -100,7 +100,7 @@ items: - stellar:JPYC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5 - stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP country_codes: - - US + - USA sell_delivery_methods: - name: WIRE description: Send USD directly to the Anchor's bank account. diff --git a/docker-compose.yaml b/docker-compose.yaml index 9d159aef6c..7b9a1ede12 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,7 +12,7 @@ services: To start the services: `docker-compose --profile v2-stable up` maintainer: "jamie@stellar.org" - latest-servers: + stable-servers: extends: file: service-runner/src/main/resources/common/docker-compose.yaml service: dev-servers diff --git a/docs/README.md b/docs/README.md index 23f633b58b..907d3d76d1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ [![License](https://badgen.net/badge/license/Apache%202/blue?icon=github&label=License)](https://github.com/stellar/java-stellar-anchor-sdk/blob/develop/LICENSE) [![GitHub Version](https://badgen.net/github/release/stellar/java-stellar-anchor-sdk?icon=github&label=Latest%20release)](https://github.com/stellar/java-stellar-anchor-sdk/releases) -[![Docker](https://badgen.net/badge/Latest%20Release/v3.0.1/blue?icon=docker)](https://hub.docker.com/r/stellar/anchor-platform/tags?page=1&name=3.0.1) +[![Docker](https://badgen.net/badge/Latest%20Release/v3.0.0/blue?icon=docker)](https://hub.docker.com/r/stellar/anchor-platform/tags?page=1&name=3.0.0) ![Develop Branch](https://github.com/stellar/java-stellar-anchor-sdk/actions/workflows/on_push_to_develop.yml/badge.svg?branch=develop)
diff --git a/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/AbstractIntegrationTests.kt b/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/AbstractIntegrationTests.kt index 1e8e4bc2ea..ca70c81646 100644 --- a/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/AbstractIntegrationTests.kt +++ b/essential-tests/src/testFixtures/kotlin/org/stellar/anchor/platform/AbstractIntegrationTests.kt @@ -69,7 +69,7 @@ abstract class AbstractIntegrationTests(val config: TestConfig) { .records for (payment in payments) { if (payment is PaymentOperationResponse) { - if (payment.transaction.memo.toString() == TEST_PAYMENT_MEMO) { + if (payment.transaction.get().memo.toString() == TEST_PAYMENT_MEMO) { println("Found test payment") // initialize the test payment value pairs for injection testPaymentValues = diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eb6ea6644e..ac2a0accd2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,8 +5,7 @@ assertj = "3.26.0" aws-iam-auth = "2.1.1" aws-rds = "1.12.759" aws-sqs = "1.12.757" -bcastle = "1.79" -bcutil = "1.79" +bcastle = "1.77" commons-beanutils = "1.9.4" commons-cli = "1.8.0" commons-codec = "1.17.0" @@ -28,7 +27,7 @@ jakarta-annotation-api = "3.0.0" jakarta-transaction-api = "2.0.1" jakarta-validation-api = "3.1.0" jakarta-xml-bind-api = "4.0.2" -java-stellar-sdk = "1.0.0" +java-stellar-sdk = "0.44.1" jjwt = "0.12.5" jsonassert = "1.5.0" junit = "5.10.3" @@ -53,7 +52,7 @@ spotbugs-annotations = "4.8.6" spring-context = "6.1.11" spring-kafka = "3.2.1" spring-retry = "2.0.6" -stellar-wallet-sdk = "2.0.0" +stellar-wallet-sdk = "1.7.1" # Plugin versions spotless = "6.25.0" @@ -68,7 +67,6 @@ aws-iam-auth = { module = "software.amazon.msk:aws-msk-iam-auth", version.ref = aws-rds = { module = "com.amazonaws:aws-java-sdk-rds", version.ref = "aws-rds" } aws-sqs = { module = "com.amazonaws:aws-java-sdk-sqs", version.ref = "aws-sqs" } bcastle = { module = "org.bouncycastle:bcprov-jdk18on", version.ref = "bcastle" } -bcutil = { module = "org.bouncycastle:bcutil-jdk18on", version.ref = "bcutil" } commons-beanutils = { module = "commons-beanutils:commons-beanutils", version.ref = "commons-beanutils" } commons-cli = { module = "commons-cli:commons-cli", version.ref = "commons-cli" } commons-codec = { module = "commons-codec:commons-codec", version.ref = "commons-codec" } @@ -92,7 +90,7 @@ jakarta-annotation-api = { module = "jakarta.annotation:jakarta.annotation-api", jakarta-transaction-api = { module = "jakarta.transaction:jakarta.transaction-api", version.ref = "jakarta-transaction-api" } jakarta-validation-api = { module = "jakarta.validation:jakarta.validation-api", version.ref = "jakarta-validation-api" } jakarta-xml-bind-api = { module = "jakarta.xml.bind:jakarta.xml.bind-api", version.ref = "jakarta-xml-bind-api" } -java-stellar-sdk = { module = "network.lightsail:stellar-sdk", version.ref = "java-stellar-sdk" } +java-stellar-sdk = { module = "com.github.stellar:java-stellar-sdk", version.ref = "java-stellar-sdk" } jjwt = { module = "io.jsonwebtoken:jjwt", version.ref = "jjwt" } jsonassert = { module = "org.skyscreamer:jsonassert", version.ref = "jsonassert" } junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } diff --git a/helm-charts/README.md b/helm-charts/README.md deleted file mode 100644 index fabd1ea4d6..0000000000 --- a/helm-charts/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Getting Started - -The following instructions will guide you through the process of setting up the Anchor Platform on a local Kubernetes cluster using Minikube. - -```bash -minikube start - -# Install external-secrets -helm repo add external-secrets https://charts.external-secrets.io -helm install external-secrets \ - external-secrets/external-secrets \ - -n external-secrets \ - --create-namespace - -# Install postgres -helm repo add bitnami https://charts.bitnami.com/bitnami -helm install postgresql-ref bitnami/postgresql --set global.postgresql.auth.postgresPassword=123456789 -helm install postgresql bitnami/postgresql --set global.postgresql.auth.postgresPassword=123456789 - -# Install Kafka -kubectl create secret generic ap-kafka-secrets --from-literal=client-passwords=123456789 --from-literal=controller-password=123456789 --from-literal=inter-broker-password=123456789 --from-literal=system-user-password=123456789 -helm install kafka bitnami/kafka --set sasl.existingSecret=ap-kafka-secrets - -# Install the secret store -helm upgrade --install fake-secret-store ./secret-store/ - -# Build the Anchor Platform image locally -eval $(minikube -p minikube docker-env) -docker build -t anchor-platform:local ../ - -# Install the reference server -helm upgrade --install reference-server ./reference-server/ -f ./reference-server/values.yaml - -# Install the Anchor Platform -helm upgrade --install anchor-platform ./sep-service/ -f ./sep-service/values.yaml - -# Install the ingress controller -helm upgrade --install ingress-nginx ingress-nginx \ - --repo https://kubernetes.github.io/ingress-nginx \ - --namespace ingress-nginx --create-namespace - -# Port forward the ingress controller -kubectl port-forward svc/ingress-nginx-controller 8080:80 -n ingress-nginx - -# Now you can access the Anchor Platform at http://localhost:8080 -``` diff --git a/helm-charts/secret-store/templates/secretstore.yaml b/helm-charts/secret-store/templates/secretstore.yaml index aee33ef0dd..0226ac15a2 100644 --- a/helm-charts/secret-store/templates/secretstore.yaml +++ b/helm-charts/secret-store/templates/secretstore.yaml @@ -11,20 +11,20 @@ spec: value: | { "POSTGRES_USER": "postgres", - "POSTGRES_PASSWORD": "123456789", + "POSTGRES_PASSWORD": "cdb1ajkMih", "SEP24_INTERACTIVE_URL_JWT_SECRET": "c5457e3a349df9002117543efa7e316dd89e666a5ce6f33a0deb13e90f3f1e9d", "SEP24_MORE_INFO_URL_JWT_SECRET": "b106cce1e32ebe342ea1e38d363fe048c7dc9c1b773658f83e22b78125785d89", "SEP6_MORE_INFO_URL_JWT_SECRET": "3a614cf5da456aaad61dc7532f6c422fc2b833c0c05102b47b1ac2e8f0bff2e8", "SEP10_JWT_SECRET": "10bb04a51338a1df86c2e807f8fe36168cf9a480d70c233452ec7e198ab33b7c", "SEP10_SIGNING_SEED": "SAX3AH622R2XT6DXWWSRIDCMMUCCMATBZ5U6XKJWDO7M2EJUBFC3AW5X", "EVENTS_QUEUE_KAFKA_USERNAME": "user1", - "EVENTS_QUEUE_KAFKA_PASSWORD": "123456789", + "EVENTS_QUEUE_KAFKA_PASSWORD": "INfioH5l7N", } - key: {{ .Values.namespace}}/reference-server-secrets value: | { "POSTGRES_USER": "postgres", - "POSTGRES_PASSWORD": "123456789", + "POSTGRES_PASSWORD": "XgvqTkecnv", "SEP6_SECRET": "SAJW2O2NH5QMMVWYAN352OEXS2RUY675A2HPK5HEG2FRR2NXPYA4OLYN", "SEP24_INTERACTIVE_JWT_KEY": "0005686076237201446d93d2ea92d1419647283e2acddbc2fffbf8d53db36b7d", "SEP24_SECRET": "SAJ34AG5XC7BWGK3GGQGCXERSEP7LZYXBBDMD33NMBASZVNKACEMNEIY", diff --git a/helm-charts/sep-service/templates/sepserver-ingress.yaml b/helm-charts/sep-service/templates/sepserver-ingress.yaml index f951c79c1d..3063ab3f63 100644 --- a/helm-charts/sep-service/templates/sepserver-ingress.yaml +++ b/helm-charts/sep-service/templates/sepserver-ingress.yaml @@ -1,28 +1,14 @@ -apiVersion: v1 -data: - {{- if .Values.ingress.responseHeaders }} - {{- range $key, $value := .Values.ingress.responseHeaders }} - {{ $key }}: {{ $value | quote }} - {{- end }} - {{- end }} -kind: ConfigMap -metadata: - name: {{ .Values.ingress.name }}-configmap - namespace: {{ .Values.namespace }} ---- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: {{ .Values.ingress.name }} + name: {{ .Values.ingress.name}} namespace: {{ .Values.namespace }} + {{- if .Values.ingress.annotations }} annotations: - {{- $annotations := dict "nginx.ingress.kubernetes.io/custom-headers" (printf "%s/%s-configmap" .Values.namespace .Values.ingress.name) }} - {{- if .Values.ingress.annotations }} - {{- $annotations = merge $annotations .Values.ingress.annotations }} - {{- end }} - {{- range $key, $value := $annotations }} - {{ $key }}: {{ $value | quote }} + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} {{- end }} + {{- end }} labels: app.kubernetes.io/name: {{ .Values.fullName }}-ingress helm.sh/chart: {{ $.Chart.Name }}-{{ $.Chart.Version }} diff --git a/helm-charts/sep-service/values.yaml b/helm-charts/sep-service/values.yaml index 309ec6727a..6236e0b13e 100644 --- a/helm-charts/sep-service/values.yaml +++ b/helm-charts/sep-service/values.yaml @@ -295,7 +295,7 @@ assets_config: | - stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP - stellar:JPYC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP country_codes: - - US + - USA sell_delivery_methods: - name: WIRE description: Send USD directly to the Anchor's bank account. diff --git a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/StringHelperKt.kt b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/StringHelperKt.kt deleted file mode 100644 index 2e6d68ef04..0000000000 --- a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/StringHelperKt.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.stellar.reference - -/** - * Converts a dot-separated string to camelCase. For example: - "kt.reference.server.config" becomes - * "ktReferenceServerConfig" - * - * @param s The dot-separated string to be converted. - * @return A string in camelCase format. - * @throws NullPointerException If the input string is null. - */ -fun dotToCamelCase(s: String): String { - return s.split(".") // Split by dot - .mapIndexed { index, part -> - if (part.isEmpty()) { - "" // Ignore empty parts caused by consecutive dots or leading/trailing dots - } else if (index == 0) { - part.replaceFirstChar { - it.lowercaseChar() - } // Ensure the first part starts with a lowercase letter - } else { - part.replaceFirstChar { it.uppercaseChar() } // Capitalize the first letter of other parts - } - } - .joinToString("") // Join all parts back together as camelCase -} diff --git a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/data/Config.kt b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/data/Config.kt index afbcd938f7..6d012fcc0d 100644 --- a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/data/Config.kt +++ b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/data/Config.kt @@ -3,7 +3,7 @@ package org.stellar.reference.data import com.sksamuel.hoplite.ConfigAlias import org.stellar.sdk.KeyPair -data class LocationConfig(val ktReferenceServerConfig: String?) +data class LocationConfig(val ktReferenceServerConfig: String) data class Config( @ConfigAlias("app") val appSettings: AppSettings, diff --git a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/di/ConfigContainer.kt b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/di/ConfigContainer.kt index 32d0094385..16038e769f 100644 --- a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/di/ConfigContainer.kt +++ b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/di/ConfigContainer.kt @@ -2,8 +2,6 @@ package org.stellar.reference.di import com.sksamuel.hoplite.* import org.stellar.reference.data.Config -import org.stellar.reference.data.LocationConfig -import org.stellar.reference.dotToCamelCase class ConfigContainer(envMap: Map?) { var config: Config = readCfg(envMap) @@ -22,26 +20,14 @@ class ConfigContainer(envMap: Map?) { } private fun readCfg(envMap: Map?): Config { - // The location of the config file is determined by the environment variable first - val locationCfgBuilder = - ConfigLoaderBuilder.default().addPropertySource(PropertySource.environment()) - - // Add environment variables as a property source for the config object - val cfgBuilder = ConfigLoaderBuilder.default().addPropertySource(PropertySource.environment()) - - // Add any environment variable overrides from the envMap + val cfgBuilder = ConfigLoaderBuilder.default() + // Add environment variables as a property source. + cfgBuilder.addPropertySource(PropertySource.environment()) envMap?.run { - // env variables override cfgBuilder.addMapSource(this) - - // for the location config, we need to convert the keys to camel case - val camelEnvMap = this.mapKeys { (key, _) -> dotToCamelCase(key) } - locationCfgBuilder.addMapSource(camelEnvMap) - } - - val locationConfig = locationCfgBuilder.build().loadConfigOrThrow() - if (locationConfig.ktReferenceServerConfig != null) { - cfgBuilder.addFileSource(locationConfig.ktReferenceServerConfig) + if (envMap[KT_REFERENCE_SERVER_CONFIG] != null) { + cfgBuilder.addFileSource(envMap[KT_REFERENCE_SERVER_CONFIG]!!) + } } return cfgBuilder.build().loadConfigOrThrow() } diff --git a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/event/processor/Sep6EventProcessor.kt b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/event/processor/Sep6EventProcessor.kt index 864c36a7aa..adbe0fd7b9 100644 --- a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/event/processor/Sep6EventProcessor.kt +++ b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/event/processor/Sep6EventProcessor.kt @@ -1,6 +1,5 @@ package org.stellar.reference.event.processor -import java.math.BigDecimal import java.time.Instant import java.util.* import kotlinx.coroutines.runBlocking @@ -18,9 +17,6 @@ import org.stellar.reference.log import org.stellar.reference.service.SepHelper import org.stellar.reference.transactionWithRetry import org.stellar.sdk.* -import org.stellar.sdk.exception.BadRequestException -import org.stellar.sdk.operations.PaymentOperation -import org.stellar.sdk.responses.TransactionResponse class Sep6EventProcessor( private val config: Config, @@ -442,22 +438,14 @@ class Sep6EventProcessor( .addPreconditions( TransactionPreconditions.builder().timeBounds(TimeBounds.expiresAfter(60)).build() ) - .addOperation( - PaymentOperation.builder() - .destination(destination) - .asset(asset) - .amount(BigDecimal(amount)) - .build() - ) + .addOperation(PaymentOperation.Builder(destination, asset, amount).build()) .build() transaction.sign(KeyPair.fromSecretSeed(config.appSettings.secret)) - val txnResponse: TransactionResponse - try { - txnResponse = server.submitTransaction(transaction) - } catch (e: BadRequestException) { - throw RuntimeException("Error submitting transaction: ${e.problem?.extras?.resultCodes}") + val txnResponse = server.submitTransaction(transaction) + if (!txnResponse.isSuccess) { + throw RuntimeException("Error submitting transaction: ${txnResponse.extras.resultCodes}") } - assert(txnResponse.successful) + return txnResponse.hash } diff --git a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/service/SepHelper.kt b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/service/SepHelper.kt index 0f26f6622e..6dae87760e 100644 --- a/kotlin-reference-server/src/main/kotlin/org/stellar/reference/service/SepHelper.kt +++ b/kotlin-reference-server/src/main/kotlin/org/stellar/reference/service/SepHelper.kt @@ -20,9 +20,6 @@ import org.stellar.anchor.util.GsonUtils import org.stellar.reference.data.* import org.stellar.reference.data.Transaction import org.stellar.sdk.* -import org.stellar.sdk.exception.BadRequestException -import org.stellar.sdk.operations.PaymentOperation -import org.stellar.sdk.responses.TransactionResponse class SepHelper(private val cfg: Config) { private val log = KotlinLogging.logger {} @@ -100,11 +97,7 @@ class SepHelper(private val cfg: Config) { TransactionPreconditions.builder().timeBounds(TimeBounds.expiresAfter(60)).build() ) .addOperation( - PaymentOperation.builder() - .destination(destinationAddress) - .asset(asset) - .amount(amount) - .build() + PaymentOperation.Builder(destinationAddress, asset, amount.toPlainString()).build() ) if (memo != null && memoType != null) { @@ -122,15 +115,14 @@ class SepHelper(private val cfg: Config) { transaction.sign(cfg.sep24.keyPair) - val resp: TransactionResponse - try { - resp = server.submitTransaction(transaction) - } catch (e: BadRequestException) { + val resp = server.submitTransaction(transaction) + + if (!resp.isSuccess) { throw Exception( - "Failed to submit transaction with code: ${e.problem?.extras?.resultCodes?.transactionResultCode}" + "Failed to submit transaction with code: ${resp?.extras?.resultCodes?.transactionResultCode}" ) } - assert(resp.successful) + return resp.hash } diff --git a/platform/build.gradle.kts b/platform/build.gradle.kts index 6980ad127a..c0e9adea2f 100644 --- a/platform/build.gradle.kts +++ b/platform/build.gradle.kts @@ -26,7 +26,6 @@ dependencies { implementation(libs.aws.rds) implementation(libs.aws.sqs) implementation(libs.bcastle) - implementation(libs.bcutil) implementation(libs.commons.beanutils) implementation(libs.commons.cli) implementation(libs.commons.io) diff --git a/platform/src/main/java/org/stellar/anchor/platform/component/platform/PlatformServerBeans.java b/platform/src/main/java/org/stellar/anchor/platform/component/platform/PlatformServerBeans.java index 4332841576..8964e34111 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/component/platform/PlatformServerBeans.java +++ b/platform/src/main/java/org/stellar/anchor/platform/component/platform/PlatformServerBeans.java @@ -19,7 +19,7 @@ import org.stellar.anchor.filter.PlatformAuthJwtFilter; import org.stellar.anchor.horizon.Horizon; import org.stellar.anchor.platform.apiclient.CustodyApiClient; -import org.stellar.anchor.platform.condition.OnAnySepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAnySepsEnabled; import org.stellar.anchor.platform.config.PlatformApiConfig; import org.stellar.anchor.platform.config.PlatformServerConfig; import org.stellar.anchor.platform.config.PropertyCustodyConfig; @@ -71,6 +71,7 @@ public FilterRegistrationBean platformTokenFilter( } @Bean + @ConditionalOnAnySepsEnabled(seps = {"sep31"}) Sep31DepositInfoGenerator sep31DepositInfoGenerator( Sep31Config sep31Config, Optional custodyApiClient) throws InvalidConfigException { @@ -93,6 +94,7 @@ Sep31DepositInfoGenerator sep31DepositInfoGenerator( } @Bean + @ConditionalOnAnySepsEnabled(seps = {"sep24"}) Sep24DepositInfoGenerator sep24DepositInfoGenerator( Sep24Config sep24Config, Optional custodyApiClient) throws InvalidConfigException { @@ -115,6 +117,7 @@ Sep24DepositInfoGenerator sep24DepositInfoGenerator( } @Bean + @ConditionalOnAnySepsEnabled(seps = {"sep6"}) Sep6DepositInfoGenerator sep6DepositInfoGenerator( Sep6Config sep6Config, AssetService assetService, Optional custodyApiClient) throws InvalidConfigException { diff --git a/platform/src/main/java/org/stellar/anchor/platform/component/sep/SepBeans.java b/platform/src/main/java/org/stellar/anchor/platform/component/sep/SepBeans.java index cf43c80a87..945f25e6c8 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/component/sep/SepBeans.java +++ b/platform/src/main/java/org/stellar/anchor/platform/component/sep/SepBeans.java @@ -18,8 +18,8 @@ import org.stellar.anchor.event.EventService; import org.stellar.anchor.filter.Sep10JwtFilter; import org.stellar.anchor.horizon.Horizon; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; -import org.stellar.anchor.platform.condition.OnAnySepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAnySepsEnabled; import org.stellar.anchor.platform.config.*; import org.stellar.anchor.platform.service.SimpleInteractiveUrlConstructor; import org.stellar.anchor.sep1.Sep1Service; @@ -101,19 +101,19 @@ public FilterRegistrationBean sep10TokenFilter( } @Bean - @OnAllSepsEnabled(seps = {"sep1"}) + @ConditionalOnAllSepsEnabled(seps = {"sep1"}) Sep1Service sep1Service(Sep1Config sep1Config) { return new Sep1Service(sep1Config); } @Bean - @OnAnySepsEnabled(seps = {"sep6", "sep10", "sep24"}) + @ConditionalOnAnySepsEnabled(seps = {"sep6", "sep10", "sep24"}) ClientFinder clientFinder(Sep10Config sep10Config, ClientService clientService) { return new ClientFinder(sep10Config, clientService); } @Bean - @OnAllSepsEnabled(seps = {"sep6"}) + @ConditionalOnAllSepsEnabled(seps = {"sep6"}) Sep6Service sep6Service( AppConfig appConfig, Sep6Config sep6Config, @@ -139,7 +139,7 @@ Sep6Service sep6Service( } @Bean - @OnAllSepsEnabled(seps = {"sep10"}) + @ConditionalOnAllSepsEnabled(seps = {"sep10"}) Sep10Service sep10Service( AppConfig appConfig, SecretConfig secretConfig, @@ -152,7 +152,7 @@ Sep10Service sep10Service( } @Bean - @OnAllSepsEnabled(seps = {"sep12"}) + @ConditionalOnAllSepsEnabled(seps = {"sep12"}) Sep12Service sep12Service( CustomerIntegration customerIntegration, PlatformApiClient platformApiClient, @@ -161,7 +161,7 @@ Sep12Service sep12Service( } @Bean - @OnAllSepsEnabled(seps = {"sep24"}) + @ConditionalOnAllSepsEnabled(seps = {"sep24"}) Sep24Service sep24Service( AppConfig appConfig, Sep24Config sep24Config, @@ -204,7 +204,7 @@ InteractiveUrlConstructor interactiveUrlConstructor( } @Bean - @OnAllSepsEnabled(seps = {"sep31"}) + @ConditionalOnAllSepsEnabled(seps = {"sep31"}) Sep31Service sep31Service( AppConfig appConfig, Sep10Config sep10Config, @@ -228,7 +228,7 @@ Sep31Service sep31Service( } @Bean - @OnAllSepsEnabled(seps = {"sep38"}) + @ConditionalOnAllSepsEnabled(seps = {"sep38"}) Sep38Service sep38Service( Sep38Config sep38Config, AssetService assetService, diff --git a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepsEnabled.java b/platform/src/main/java/org/stellar/anchor/platform/condition/ConditionalOnAllSepsEnabled.java similarity index 91% rename from platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepsEnabled.java rename to platform/src/main/java/org/stellar/anchor/platform/condition/ConditionalOnAllSepsEnabled.java index c345ab59ce..ceb882700d 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepsEnabled.java +++ b/platform/src/main/java/org/stellar/anchor/platform/condition/ConditionalOnAllSepsEnabled.java @@ -8,7 +8,7 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnAllSepEnabledCondition.class) -public @interface OnAllSepsEnabled { +public @interface ConditionalOnAllSepsEnabled { /** * The list of seps that are checked if enabled. * diff --git a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepsEnabled.java b/platform/src/main/java/org/stellar/anchor/platform/condition/ConditionalOnAnySepsEnabled.java similarity index 91% rename from platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepsEnabled.java rename to platform/src/main/java/org/stellar/anchor/platform/condition/ConditionalOnAnySepsEnabled.java index 2a769e9b65..6c97535af2 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepsEnabled.java +++ b/platform/src/main/java/org/stellar/anchor/platform/condition/ConditionalOnAnySepsEnabled.java @@ -8,7 +8,7 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnAnySepEnabledCondition.class) -public @interface OnAnySepsEnabled { +public @interface ConditionalOnAnySepsEnabled { /** * The list of seps that are checked if enabled. * diff --git a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepEnabledCondition.java b/platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepEnabledCondition.java index 036bc351ec..111957ed1c 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepEnabledCondition.java +++ b/platform/src/main/java/org/stellar/anchor/platform/condition/OnAllSepEnabledCondition.java @@ -7,7 +7,7 @@ public class OnAllSepEnabledCondition extends AbstractOnSepsEnabled { @Override String getAnnotatingClass() { - return OnAllSepsEnabled.class.getName(); + return ConditionalOnAllSepsEnabled.class.getName(); } @Override diff --git a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepEnabledCondition.java b/platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepEnabledCondition.java index f5b4ed1780..f30f5ebed8 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepEnabledCondition.java +++ b/platform/src/main/java/org/stellar/anchor/platform/condition/OnAnySepEnabledCondition.java @@ -8,7 +8,7 @@ public class OnAnySepEnabledCondition extends AbstractOnSepsEnabled { @Override String getAnnotatingClass() { - return OnAnySepsEnabled.class.getName(); + return ConditionalOnAnySepsEnabled.class.getName(); } @Override diff --git a/platform/src/main/java/org/stellar/anchor/platform/config/PropertySep10Config.java b/platform/src/main/java/org/stellar/anchor/platform/config/PropertySep10Config.java index a950ec8d02..9a08dba94b 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/config/PropertySep10Config.java +++ b/platform/src/main/java/org/stellar/anchor/platform/config/PropertySep10Config.java @@ -21,7 +21,6 @@ import org.stellar.anchor.util.KeyUtil; import org.stellar.anchor.util.NetUtil; import org.stellar.sdk.*; -import org.stellar.sdk.operations.ManageDataOperation; @Data public class PropertySep10Config implements Sep10Config, Validator { @@ -113,7 +112,7 @@ void validateConfig(Errors errors) { if (isNotEmpty(webAuthDomain)) { try { - ManageDataOperation.builder().name(webAuthDomain).value(new byte[64]).build(); + new ManageDataOperation.Builder(webAuthDomain, new byte[64]).build(); } catch (IllegalArgumentException iaex) { errors.rejectValue( "webAuthDomain", @@ -191,10 +190,7 @@ void validateCustodialAccounts(Errors errors) { private void validateDomain(Errors errors, String domain) { try { - ManageDataOperation.builder() - .name(String.format("%s %s", domain, "auth")) - .value(new byte[64]) - .build(); + new ManageDataOperation.Builder(String.format("%s %s", domain, "auth"), new byte[64]).build(); } catch (IllegalArgumentException iaex) { errors.rejectValue( "homeDomain", diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep10Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep10Controller.java index 3c016c6132..041060dc10 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep10Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep10Controller.java @@ -2,6 +2,7 @@ import static org.stellar.anchor.util.Log.*; +import java.io.IOException; import java.net.URISyntaxException; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -14,13 +15,13 @@ import org.stellar.anchor.api.sep.sep10.ChallengeResponse; import org.stellar.anchor.api.sep.sep10.ValidationRequest; import org.stellar.anchor.api.sep.sep10.ValidationResponse; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep10.Sep10Service; -import org.stellar.sdk.exception.InvalidSep10ChallengeException; +import org.stellar.sdk.InvalidSep10ChallengeException; @RestController @CrossOrigin(origins = "*") -@OnAllSepsEnabled(seps = {"sep10"}) +@ConditionalOnAllSepsEnabled(seps = {"sep10"}) public class Sep10Controller { private final Sep10Service sep10Service; @@ -64,7 +65,8 @@ public ChallengeResponse createChallenge( produces = {MediaType.APPLICATION_JSON_VALUE}, method = {RequestMethod.POST}) public ValidationResponse validateChallenge( - @RequestParam(name = "transaction") String transaction) throws SepValidationException { + @RequestParam(name = "transaction") String transaction) + throws InvalidSep10ChallengeException, IOException, SepValidationException { debugF("POST /auth transaction={}", transaction); return validateChallenge(ValidationRequest.of(transaction)); } @@ -77,7 +79,7 @@ public ValidationResponse validateChallenge( method = {RequestMethod.POST}) public ValidationResponse validateChallenge( @RequestBody(required = false) ValidationRequest validationRequest) - throws SepValidationException { + throws InvalidSep10ChallengeException, IOException, SepValidationException { debug("POST /auth details:", validationRequest); return sep10Service.validateChallenge(validationRequest); } diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep12Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep12Controller.java index 8067fd8bfe..7aa107db5e 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep12Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep12Controller.java @@ -16,14 +16,14 @@ import org.springframework.web.multipart.MultipartHttpServletRequest; import org.stellar.anchor.api.sep.sep12.*; import org.stellar.anchor.auth.Sep10Jwt; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep12.Sep12Service; import org.stellar.anchor.util.GsonUtils; @RestController @CrossOrigin(origins = "*") @RequestMapping("/sep12") -@OnAllSepsEnabled(seps = {"sep12"}) +@ConditionalOnAllSepsEnabled(seps = {"sep12"}) public class Sep12Controller { private final Sep12Service sep12Service; diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep1Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep1Controller.java index 4881055b9c..bf18b5158a 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep1Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep1Controller.java @@ -10,12 +10,12 @@ import org.stellar.anchor.api.exception.SepNotFoundException; import org.stellar.anchor.api.sep.SepExceptionResponse; import org.stellar.anchor.config.Sep1Config; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep1.Sep1Service; @RestController @CrossOrigin(origins = "*") -@OnAllSepsEnabled(seps = {"sep1"}) +@ConditionalOnAllSepsEnabled(seps = {"sep1"}) public class Sep1Controller { private final Sep1Config sep1Config; private final Sep1Service sep1Service; diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep24Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep24Controller.java index 9bef81cec4..b2eebe9e40 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep24Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep24Controller.java @@ -16,13 +16,13 @@ import org.stellar.anchor.api.sep.SepExceptionResponse; import org.stellar.anchor.api.sep.sep24.*; import org.stellar.anchor.auth.Sep10Jwt; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep24.Sep24Service; @RestController @CrossOrigin(origins = "*") @RequestMapping("/sep24") -@OnAllSepsEnabled(seps = {"sep24"}) +@ConditionalOnAllSepsEnabled(seps = {"sep24"}) public class Sep24Controller { private final Sep24Service sep24Service; diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep31Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep31Controller.java index 7d82428410..d6aa9482a8 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep31Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep31Controller.java @@ -14,13 +14,13 @@ import org.stellar.anchor.api.exception.Sep31MissingFieldException; import org.stellar.anchor.api.sep.sep31.*; import org.stellar.anchor.auth.Sep10Jwt; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep31.Sep31Service; @RestController @CrossOrigin(origins = "*") @RequestMapping("sep31") -@OnAllSepsEnabled(seps = {"sep31"}) +@ConditionalOnAllSepsEnabled(seps = {"sep31"}) public class Sep31Controller { private final Sep31Service sep31Service; diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep38Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep38Controller.java index 575380f31a..b1365dc7ae 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep38Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep38Controller.java @@ -15,14 +15,14 @@ import org.stellar.anchor.api.sep.SepExceptionResponse; import org.stellar.anchor.api.sep.sep38.*; import org.stellar.anchor.auth.Sep10Jwt; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep38.Sep38Service; import org.stellar.anchor.util.GsonUtils; @RestController @CrossOrigin(origins = "*") @RequestMapping("/sep38") -@OnAllSepsEnabled(seps = {"sep38"}) +@ConditionalOnAllSepsEnabled(seps = {"sep38"}) public class Sep38Controller { private final Sep38Service sep38Service; private static final Gson gson = GsonUtils.getInstance(); diff --git a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java index 877b7bb58d..cbf3856238 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java +++ b/platform/src/main/java/org/stellar/anchor/platform/controller/sep/Sep6Controller.java @@ -11,13 +11,13 @@ import org.stellar.anchor.api.exception.SepException; import org.stellar.anchor.api.sep.sep6.*; import org.stellar.anchor.auth.Sep10Jwt; -import org.stellar.anchor.platform.condition.OnAllSepsEnabled; +import org.stellar.anchor.platform.condition.ConditionalOnAllSepsEnabled; import org.stellar.anchor.sep6.Sep6Service; @RestController @CrossOrigin(origins = "*") @RequestMapping("sep6") -@OnAllSepsEnabled(seps = {"sep6"}) +@ConditionalOnAllSepsEnabled(seps = {"sep6"}) public class Sep6Controller { private final Sep6Service sep6Service; diff --git a/platform/src/main/java/org/stellar/anchor/platform/custody/CustodyPayment.java b/platform/src/main/java/org/stellar/anchor/platform/custody/CustodyPayment.java index 78bf20ddfc..0254f29c67 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/custody/CustodyPayment.java +++ b/platform/src/main/java/org/stellar/anchor/platform/custody/CustodyPayment.java @@ -67,7 +67,7 @@ public static CustodyPayment fromPayment( id = paymentOperation.get().getId().toString(); to = paymentOperation.get().getTo(); amount = paymentOperation.get().getAmount(); - assetType = paymentOperation.get().getAssetType(); + assetType = paymentOperation.get().getAsset().getType(); assetName = paymentOperation.get().getAsset().toString(); if (paymentOperation.get().getAsset() instanceof AssetTypeCreditAlphaNum) { @@ -76,22 +76,23 @@ public static CustodyPayment fromPayment( assetCode = issuedAsset.getCode(); assetIssuer = issuedAsset.getIssuer(); } else if (paymentOperation.get().getAsset() instanceof AssetTypeNative) { - assetCode = paymentOperation.get().getAssetType(); // "native" + AssetTypeNative issuedAsset = (AssetTypeNative) paymentOperation.get().getAsset(); + assetCode = issuedAsset.getType(); } String sourceAccount = paymentOperation.get().getSourceAccount() != null ? paymentOperation.get().getSourceAccount() - : paymentOperation.get().getTransaction().getSourceAccount(); + : paymentOperation.get().getTransaction().get().getSourceAccount(); from = paymentOperation.get().getFrom() != null ? paymentOperation.get().getFrom() : sourceAccount; - Memo memo = paymentOperation.get().getTransaction().getMemo(); + Memo memo = paymentOperation.get().getTransaction().get().getMemo(); transactionMemo = MemoHelper.memoAsString(memo); transactionMemoType = MemoHelper.memoTypeAsString(memo); - transactionEnvelope = paymentOperation.get().getTransaction().getEnvelopeXdr(); + transactionEnvelope = paymentOperation.get().getTransaction().get().getEnvelopeXdr(); } return CustodyPayment.builder() @@ -139,7 +140,7 @@ public static CustodyPayment fromPathPayment( id = pathPaymentOperation.get().getId().toString(); to = pathPaymentOperation.get().getTo(); amount = pathPaymentOperation.get().getAmount(); - assetType = pathPaymentOperation.get().getAssetType(); + assetType = pathPaymentOperation.get().getAsset().getType(); assetName = pathPaymentOperation.get().getAsset().toString(); if (pathPaymentOperation.get().getAsset() instanceof AssetTypeCreditAlphaNum) { @@ -148,22 +149,23 @@ public static CustodyPayment fromPathPayment( assetCode = issuedAsset.getCode(); assetIssuer = issuedAsset.getIssuer(); } else if (pathPaymentOperation.get().getAsset() instanceof AssetTypeNative) { - assetCode = pathPaymentOperation.get().getAssetType(); // "native" + AssetTypeNative issuedAsset = (AssetTypeNative) pathPaymentOperation.get().getAsset(); + assetCode = issuedAsset.getType(); } String sourceAccount = pathPaymentOperation.get().getSourceAccount() != null ? pathPaymentOperation.get().getSourceAccount() - : pathPaymentOperation.get().getTransaction().getSourceAccount(); + : pathPaymentOperation.get().getTransaction().get().getSourceAccount(); from = pathPaymentOperation.get().getFrom() != null ? pathPaymentOperation.get().getFrom() : sourceAccount; - Memo memo = pathPaymentOperation.get().getTransaction().getMemo(); + Memo memo = pathPaymentOperation.get().getTransaction().get().getMemo(); transactionMemo = MemoHelper.memoAsString(memo); transactionMemoType = MemoHelper.memoTypeAsString(memo); - transactionEnvelope = pathPaymentOperation.get().getTransaction().getEnvelopeXdr(); + transactionEnvelope = pathPaymentOperation.get().getTransaction().get().getEnvelopeXdr(); } return CustodyPayment.builder() diff --git a/platform/src/main/java/org/stellar/anchor/platform/job/TrustlineCheckJob.java b/platform/src/main/java/org/stellar/anchor/platform/job/TrustlineCheckJob.java index 7239f7a7a8..40f8454358 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/job/TrustlineCheckJob.java +++ b/platform/src/main/java/org/stellar/anchor/platform/job/TrustlineCheckJob.java @@ -2,6 +2,7 @@ import static org.stellar.anchor.util.Log.info; +import java.io.IOException; import java.time.Instant; import java.time.temporal.ChronoUnit; import org.springframework.scheduling.annotation.Scheduled; @@ -12,7 +13,6 @@ import org.stellar.anchor.platform.data.JdbcTransactionPendingTrust; import org.stellar.anchor.platform.data.JdbcTransactionPendingTrustRepo; import org.stellar.anchor.platform.rpc.NotifyTrustSetHandler; -import org.stellar.sdk.exception.NetworkException; public class TrustlineCheckJob { @@ -50,7 +50,7 @@ public void checkTrust() throws AnchorException { boolean trustlineConfigured; try { trustlineConfigured = horizon.isTrustlineConfigured(t.getAccount(), t.getAsset()); - } catch (NetworkException ex) { + } catch (IOException ex) { trustlineConfigured = false; } diff --git a/platform/src/main/java/org/stellar/anchor/platform/observer/ObservedPayment.java b/platform/src/main/java/org/stellar/anchor/platform/observer/ObservedPayment.java index c1e436d3ac..fa42401f7a 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/observer/ObservedPayment.java +++ b/platform/src/main/java/org/stellar/anchor/platform/observer/ObservedPayment.java @@ -6,9 +6,7 @@ import org.stellar.anchor.api.asset.AssetInfo; import org.stellar.anchor.api.exception.SepException; import org.stellar.anchor.util.MemoHelper; -import org.stellar.sdk.AssetTypeCreditAlphaNum; -import org.stellar.sdk.AssetTypeNative; -import org.stellar.sdk.Memo; +import org.stellar.sdk.*; import org.stellar.sdk.responses.operations.PathPaymentBaseOperationResponse; import org.stellar.sdk.responses.operations.PaymentOperationResponse; @@ -46,7 +44,8 @@ public static ObservedPayment fromPaymentOperationResponse(PaymentOperationRespo throws SepException { String assetCode = null, assetIssuer = null; - if (paymentOp.getAsset() instanceof AssetTypeCreditAlphaNum issuedAsset) { + if (paymentOp.getAsset() instanceof AssetTypeCreditAlphaNum) { + AssetTypeCreditAlphaNum issuedAsset = (AssetTypeCreditAlphaNum) paymentOp.getAsset(); assetCode = issuedAsset.getCode(); assetIssuer = issuedAsset.getIssuer(); } else if (paymentOp.getAsset() instanceof AssetTypeNative) { @@ -56,16 +55,16 @@ public static ObservedPayment fromPaymentOperationResponse(PaymentOperationRespo String sourceAccount = paymentOp.getSourceAccount() != null ? paymentOp.getSourceAccount() - : paymentOp.getTransaction().getSourceAccount(); + : paymentOp.getTransaction().get().getSourceAccount(); String from = paymentOp.getFrom() != null ? paymentOp.getFrom() : sourceAccount; - Memo memo = paymentOp.getTransaction().getMemo(); + Memo memo = paymentOp.getTransaction().get().getMemo(); return ObservedPayment.builder() .id(paymentOp.getId().toString()) .type(Type.PAYMENT) .from(from) .to(paymentOp.getTo()) .amount(paymentOp.getAmount()) - .assetType(paymentOp.getAssetType()) + .assetType(paymentOp.getAsset().getType()) .assetCode(assetCode) .assetIssuer(assetIssuer) .assetName(paymentOp.getAsset().toString()) @@ -74,7 +73,7 @@ public static ObservedPayment fromPaymentOperationResponse(PaymentOperationRespo .transactionHash(paymentOp.getTransactionHash()) .transactionMemo(MemoHelper.memoAsString(memo)) .transactionMemoType(MemoHelper.memoTypeAsString(memo)) - .transactionEnvelope(paymentOp.getTransaction().getEnvelopeXdr()) + .transactionEnvelope(paymentOp.getTransaction().get().getEnvelopeXdr()) .build(); } @@ -102,21 +101,21 @@ public static ObservedPayment fromPathPaymentOperationResponse( String sourceAccount = pathPaymentOp.getSourceAccount() != null ? pathPaymentOp.getSourceAccount() - : pathPaymentOp.getTransaction().getSourceAccount(); + : pathPaymentOp.getTransaction().get().getSourceAccount(); String from = pathPaymentOp.getFrom() != null ? pathPaymentOp.getFrom() : sourceAccount; - Memo memo = pathPaymentOp.getTransaction().getMemo(); + Memo memo = pathPaymentOp.getTransaction().get().getMemo(); return ObservedPayment.builder() .id(pathPaymentOp.getId().toString()) .type(Type.PATH_PAYMENT) .from(from) .to(pathPaymentOp.getTo()) .amount(pathPaymentOp.getAmount()) - .assetType(pathPaymentOp.getAssetType()) + .assetType(pathPaymentOp.getAsset().getType()) .assetCode(assetCode) .assetIssuer(assetIssuer) .assetName(pathPaymentOp.getAsset().toString()) .sourceAmount(pathPaymentOp.getSourceAmount()) - .sourceAssetType(pathPaymentOp.getSourceAssetType()) + .sourceAssetType(pathPaymentOp.getSourceAsset().getType()) .sourceAssetCode(sourceAssetCode) .sourceAssetIssuer(sourceAssetIssuer) .sourceAssetName(pathPaymentOp.getSourceAsset().toString()) @@ -125,7 +124,7 @@ public static ObservedPayment fromPathPaymentOperationResponse( .transactionHash(pathPaymentOp.getTransactionHash()) .transactionMemo(MemoHelper.memoAsString(memo)) .transactionMemoType(MemoHelper.memoTypeAsString(memo)) - .transactionEnvelope(pathPaymentOp.getTransaction().getEnvelopeXdr()) + .transactionEnvelope(pathPaymentOp.getTransaction().get().getEnvelopeXdr()) .build(); } diff --git a/platform/src/main/java/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserver.java b/platform/src/main/java/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserver.java index 71e965ff94..8e17e69011 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserver.java +++ b/platform/src/main/java/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserver.java @@ -11,6 +11,7 @@ import static org.stellar.anchor.util.StringHelper.isEmpty; import com.google.gson.annotations.SerializedName; +import java.io.IOException; import java.time.Duration; import java.time.Instant; import java.util.*; @@ -36,7 +37,6 @@ import org.stellar.anchor.util.ExponentialBackoffTimer; import org.stellar.anchor.util.Log; import org.stellar.sdk.Server; -import org.stellar.sdk.exception.NetworkException; import org.stellar.sdk.requests.EventListener; import org.stellar.sdk.requests.PaymentsRequestBuilder; import org.stellar.sdk.requests.RequestBuilder; @@ -148,8 +148,8 @@ SSEStream startSSEStream() { new EventListener<>() { @Override public void onEvent(OperationResponse operationResponse) { - if (operationResponse.getTransaction() != null) { - metricLatestBlockRead.set(operationResponse.getTransaction().getLedger()); + if (operationResponse.getTransaction().isPresent()) { + metricLatestBlockRead.set(operationResponse.getTransaction().get().getLedger()); if (isHealthy()) { debugF("Received event {}", operationResponse.getId()); @@ -160,7 +160,8 @@ public void onEvent(OperationResponse operationResponse) { try { debugF("Dispatching event {}", operationResponse.getId()); handleEvent(operationResponse); - metricLatestBlockProcessed.set(operationResponse.getTransaction().getLedger()); + metricLatestBlockProcessed.set( + operationResponse.getTransaction().get().getLedger()); } catch (TransactionException ex) { errorEx("Error handling events", ex); @@ -335,14 +336,14 @@ String fetchLatestCursorFromNetwork() { infoF("Fetching the latest payments records. (limit={})", MIN_RESULTS); pageOpResponse = server.payments().order(RequestBuilder.Order.DESC).limit(MIN_RESULTS).execute(); - } catch (NetworkException e) { + } catch (IOException e) { Log.errorEx("Error fetching the latest /payments result.", e); return null; } if (pageOpResponse == null || pageOpResponse.getRecords() == null - || pageOpResponse.getRecords().isEmpty()) { + || pageOpResponse.getRecords().size() == 0) { info("No payments found."); return null; } @@ -352,7 +353,7 @@ String fetchLatestCursorFromNetwork() { } void handleEvent(OperationResponse operationResponse) { - if (!operationResponse.getTransactionSuccessful()) { + if (!operationResponse.isTransactionSuccessful()) { savePagingToken(operationResponse.getPagingToken()); return; } @@ -368,11 +369,12 @@ void handleEvent(OperationResponse operationResponse) { observedPayment = ObservedPayment.fromPathPaymentOperationResponse(pathPayment); } } catch (SepException ex) { - if (operationResponse.getTransaction() != null) { + if (operationResponse.getTransaction().isPresent()) { warn( String.format( "Payment of id %s contains unsupported memo %s.", - operationResponse.getId(), operationResponse.getTransaction().getMemo())); + operationResponse.getId(), + operationResponse.getTransaction().get().getMemo().toString())); } warnEx(ex); } diff --git a/platform/src/main/java/org/stellar/anchor/platform/rpc/DoStellarPaymentHandler.java b/platform/src/main/java/org/stellar/anchor/platform/rpc/DoStellarPaymentHandler.java index 8617e1fc4e..031e8f857c 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/rpc/DoStellarPaymentHandler.java +++ b/platform/src/main/java/org/stellar/anchor/platform/rpc/DoStellarPaymentHandler.java @@ -9,6 +9,7 @@ import static org.stellar.anchor.api.sep.SepTransactionStatus.PENDING_TRUST; import com.google.common.collect.ImmutableSet; +import java.io.IOException; import java.time.Instant; import java.util.Set; import org.stellar.anchor.api.exception.AnchorException; @@ -31,7 +32,6 @@ import org.stellar.anchor.sep24.Sep24TransactionStore; import org.stellar.anchor.sep31.Sep31TransactionStore; import org.stellar.anchor.sep6.Sep6TransactionStore; -import org.stellar.sdk.exception.NetworkException; public class DoStellarPaymentHandler extends RpcTransactionStatusHandler { @@ -103,7 +103,7 @@ protected SepTransactionStatus getNextStatus( default: break; } - } catch (NetworkException ex) { + } catch (IOException ex) { // assume trustline is not configured } @@ -150,7 +150,7 @@ protected void updateTransactionWithRpcRequest( try { trustlineConfigured = horizon.isTrustlineConfigured(txn6.getToAccount(), txn6.getAmountOutAsset()); - } catch (NetworkException ex) { + } catch (IOException ex) { trustlineConfigured = false; } @@ -172,7 +172,7 @@ protected void updateTransactionWithRpcRequest( try { trustlineConfigured = horizon.isTrustlineConfigured(txn24.getToAccount(), txn24.getAmountOutAsset()); - } catch (NetworkException ex) { + } catch (IOException ex) { trustlineConfigured = false; } diff --git a/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandler.java b/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandler.java index 463169e6c1..a652bd7948 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandler.java +++ b/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandler.java @@ -8,6 +8,7 @@ import static org.stellar.anchor.util.Log.errorEx; import com.google.common.collect.ImmutableSet; +import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -35,7 +36,6 @@ import org.stellar.anchor.sep24.Sep24TransactionStore; import org.stellar.anchor.sep31.Sep31TransactionStore; import org.stellar.anchor.sep6.Sep6TransactionStore; -import org.stellar.sdk.exception.NetworkException; import org.stellar.sdk.responses.operations.OperationResponse; public class NotifyOnchainFundsReceivedHandler @@ -164,7 +164,7 @@ protected void updateTransactionWithRpcRequest( JdbcSep31Transaction txn31 = (JdbcSep31Transaction) txn; txn31.setFromAccount(txnOperations.get(0).getSourceAccount()); } - } catch (NetworkException ex) { + } catch (IOException ex) { errorEx(String.format("Failed to retrieve stellar transaction by ID[%s]", stellarTxnId), ex); throw new InternalErrorException( String.format("Failed to retrieve Stellar transaction by ID[%s]", stellarTxnId), ex); diff --git a/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandler.java b/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandler.java index 1bbf62f71a..c3bb395857 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandler.java +++ b/platform/src/main/java/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandler.java @@ -10,6 +10,7 @@ import static org.stellar.anchor.util.Log.errorEx; import com.google.common.collect.ImmutableSet; +import java.io.IOException; import java.time.Instant; import java.util.HashSet; import java.util.List; @@ -32,7 +33,6 @@ import org.stellar.anchor.sep24.Sep24TransactionStore; import org.stellar.anchor.sep31.Sep31TransactionStore; import org.stellar.anchor.sep6.Sep6TransactionStore; -import org.stellar.sdk.exception.NetworkException; import org.stellar.sdk.responses.operations.OperationResponse; public class NotifyOnchainFundsSentHandler @@ -110,7 +110,7 @@ protected void updateTransactionWithRpcRequest( try { List txnOperations = horizon.getStellarTxnOperations(stellarTxnId); addStellarTransaction(txn, stellarTxnId, txnOperations); - } catch (NetworkException ex) { + } catch (IOException ex) { errorEx(String.format("Failed to retrieve stellar transaction by ID[%s]", stellarTxnId), ex); throw new InternalErrorException( String.format("Failed to retrieve Stellar transaction by ID[%s]", stellarTxnId), ex); diff --git a/platform/src/main/java/org/stellar/anchor/platform/service/RpcService.java b/platform/src/main/java/org/stellar/anchor/platform/service/RpcService.java index 957ff74782..b39d88975b 100644 --- a/platform/src/main/java/org/stellar/anchor/platform/service/RpcService.java +++ b/platform/src/main/java/org/stellar/anchor/platform/service/RpcService.java @@ -19,7 +19,7 @@ import org.stellar.anchor.platform.config.RpcConfig; import org.stellar.anchor.platform.rpc.RpcMethodHandler; import org.stellar.anchor.platform.utils.RpcUtil; -import org.stellar.sdk.exception.NetworkException; +import org.stellar.sdk.requests.ErrorResponse; public class RpcService { @@ -53,7 +53,7 @@ public List handle(List rpcRequests) { return RpcUtil.getRpcErrorResponse(rc, ex); } catch (BadRequestException ex) { return RpcUtil.getRpcErrorResponse(rc, ex); - } catch (NetworkException ex) { + } catch (ErrorResponse ex) { var message = ex.getMessage() + " Code: " + ex.getCode() + " , body: " + ex.getBody(); errorEx( diff --git a/platform/src/main/resources/example.anchor-config.yaml b/platform/src/main/resources/example.anchor-config.yaml index bf0f64a0da..fdc8cbb72e 100644 --- a/platform/src/main/resources/example.anchor-config.yaml +++ b/platform/src/main/resources/example.anchor-config.yaml @@ -212,7 +212,7 @@ assets: "stellar:JPYC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP" ], "country_codes": [ - "US" + "USA" ], "decimals": 4, "sell_delivery_methods": [ diff --git a/platform/src/test/kotlin/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserverTest.kt b/platform/src/test/kotlin/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserverTest.kt index a89432dcf5..d9af9e001b 100644 --- a/platform/src/test/kotlin/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserverTest.kt +++ b/platform/src/test/kotlin/org/stellar/anchor/platform/observer/stellar/StellarPaymentObserverTest.kt @@ -5,6 +5,7 @@ package org.stellar.anchor.platform.observer.stellar import com.google.gson.reflect.TypeToken import io.mockk.* import io.mockk.impl.annotations.MockK +import java.io.IOException import java.util.* import javax.net.ssl.SSLProtocolException import org.junit.jupiter.api.Assertions.assertEquals @@ -14,11 +15,10 @@ import org.junit.jupiter.api.Test import org.stellar.anchor.api.platform.HealthCheckStatus.RED import org.stellar.anchor.platform.config.PaymentObserverConfig.StellarPaymentObserverConfig import org.stellar.sdk.Server -import org.stellar.sdk.exception.NetworkException import org.stellar.sdk.requests.RequestBuilder import org.stellar.sdk.requests.SSEStream +import org.stellar.sdk.responses.GsonSingleton import org.stellar.sdk.responses.Page -import org.stellar.sdk.responses.gson.GsonSingleton import org.stellar.sdk.responses.operations.OperationResponse class StellarPaymentObserverTest { @@ -76,7 +76,7 @@ class StellarPaymentObserverTest { .order(RequestBuilder.Order.DESC) .limit(1) .execute() - } throws NetworkException(null, "Some IO Problem happened!") + } throws IOException("Some IO Problem happened!") gotCursor = stellarObserver.fetchStreamingCursor() verify(exactly = 2) { paymentStreamerCursorStore.load() } diff --git a/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandlerTest.kt b/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandlerTest.kt index 1839456cb5..f1efd54946 100644 --- a/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandlerTest.kt +++ b/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsReceivedHandlerTest.kt @@ -4,6 +4,7 @@ import com.google.gson.reflect.TypeToken import io.micrometer.core.instrument.Counter import io.mockk.* import io.mockk.impl.annotations.MockK +import java.io.IOException import java.time.Instant import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -45,7 +46,6 @@ import org.stellar.anchor.sep24.Sep24TransactionStore import org.stellar.anchor.sep31.Sep31TransactionStore import org.stellar.anchor.sep6.Sep6TransactionStore import org.stellar.anchor.util.GsonUtils -import org.stellar.sdk.exception.NetworkException import org.stellar.sdk.responses.operations.OperationResponse import org.stellar.sdk.responses.operations.PaymentOperationResponse @@ -577,7 +577,7 @@ class NotifyOnchainFundsReceivedHandlerTest { every { txn31Store.findByTransactionId(any()) } returns null every { txn24Store.save(capture(sep24TxnCapture)) } returns null every { horizon.getStellarTxnOperations(any()) } throws - NetworkException(400, "Invalid stellar transaction") + IOException("Invalid stellar transaction") val ex = assertThrows { handler.handle(request) } assertEquals("Failed to retrieve Stellar transaction by ID[stellarTxId]", ex.message) @@ -1037,7 +1037,7 @@ class NotifyOnchainFundsReceivedHandlerTest { every { txn31Store.findByTransactionId(any()) } returns null every { txn6Store.save(capture(sep6TxnCapture)) } returns null every { horizon.getStellarTxnOperations(any()) } throws - NetworkException(400, "Invalid stellar transaction") + IOException("Invalid stellar transaction") val ex = assertThrows { handler.handle(request) } assertEquals("Failed to retrieve Stellar transaction by ID[stellarTxId]", ex.message) diff --git a/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandlerTest.kt b/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandlerTest.kt index 5dbbf13962..8512779991 100644 --- a/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandlerTest.kt +++ b/platform/src/test/kotlin/org/stellar/anchor/platform/rpc/NotifyOnchainFundsSentHandlerTest.kt @@ -4,6 +4,7 @@ import com.google.gson.reflect.TypeToken import io.micrometer.core.instrument.Counter import io.mockk.* import io.mockk.impl.annotations.MockK +import java.io.IOException import java.time.Instant import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -44,7 +45,6 @@ import org.stellar.anchor.sep24.Sep24TransactionStore import org.stellar.anchor.sep31.Sep31TransactionStore import org.stellar.anchor.sep6.Sep6TransactionStore import org.stellar.anchor.util.GsonUtils -import org.stellar.sdk.exception.NetworkException import org.stellar.sdk.responses.operations.OperationResponse import org.stellar.sdk.responses.operations.PaymentOperationResponse @@ -163,7 +163,7 @@ class NotifyOnchainFundsSentHandlerTest { every { txn31Store.findByTransactionId(any()) } returns null every { txn24Store.save(capture(sep24TxnCapture)) } returns null every { horizon.getStellarTxnOperations(any()) } throws - NetworkException(400, "Invalid stellar transaction") + IOException("Invalid stellar transaction") val ex = assertThrows { handler.handle(request) } assertEquals("Failed to retrieve Stellar transaction by ID[stellarTxId]", ex.message) diff --git a/platform/src/test/resources/test_assets.json b/platform/src/test/resources/test_assets.json index 574641fd0c..55d78df010 100644 --- a/platform/src/test/resources/test_assets.json +++ b/platform/src/test/resources/test_assets.json @@ -65,7 +65,7 @@ "exchangeable_assets": [ "stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN" ], - "country_codes": ["US"], + "country_codes": ["USA"], "decimals": 4, "sell_delivery_methods": [ { diff --git a/platform/src/test/resources/test_assets.yaml b/platform/src/test/resources/test_assets.yaml index a3f98c80e7..e07ac851da 100644 --- a/platform/src/test/resources/test_assets.yaml +++ b/platform/src/test/resources/test_assets.yaml @@ -47,7 +47,7 @@ items: exchangeable_assets: - stellar:USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN country_codes: - - US + - USA decimals: 4 sell_delivery_methods: - name: WIRE diff --git a/platform/src/test/resources/test_sep38_get_info.json b/platform/src/test/resources/test_sep38_get_info.json index b1a17d870c..daff0d652a 100644 --- a/platform/src/test/resources/test_sep38_get_info.json +++ b/platform/src/test/resources/test_sep38_get_info.json @@ -8,7 +8,7 @@ }, { "asset": "iso4217:USD", - "country_codes": ["US"], + "country_codes": ["USA"], "decimals": 4, "sell_delivery_methods": [ { diff --git a/service-runner/src/main/resources/config/assets.yaml b/service-runner/src/main/resources/config/assets.yaml index 12706cf514..3297df2fd0 100644 --- a/service-runner/src/main/resources/config/assets.yaml +++ b/service-runner/src/main/resources/config/assets.yaml @@ -181,7 +181,7 @@ items: - stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP - stellar:USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5 country_codes: - - US + - USA sell_delivery_methods: - name: WIRE description: Send USD directly to the Anchor's bank account. @@ -204,7 +204,7 @@ items: - stellar:USDC:GDQOE23CFSUMSVQK4Y5JHPPYK73VYCNHZHA7ENKCV37P6SUEO6XQBKPP - stellar:USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5 country_codes: - - CA + - CAN sell_delivery_methods: - name: WIRE description: Send CAD directly to the Anchor's bank account. diff --git a/service-runner/src/main/resources/version-info.properties b/service-runner/src/main/resources/version-info.properties index 8d1f5a07f4..317fe995b4 100644 --- a/service-runner/src/main/resources/version-info.properties +++ b/service-runner/src/main/resources/version-info.properties @@ -1 +1 @@ -version=3.0.1 \ No newline at end of file +version=3.0.0 \ No newline at end of file diff --git a/wallet-reference-server/build.gradle.kts b/wallet-reference-server/build.gradle.kts index 5b81c58198..25992c1319 100644 --- a/wallet-reference-server/build.gradle.kts +++ b/wallet-reference-server/build.gradle.kts @@ -11,7 +11,6 @@ dependencies { implementation(libs.bundles.ktor) implementation(libs.bundles.ktor.client) implementation(libs.bcastle) - implementation(libs.bcutil) implementation(libs.google.gson) implementation(libs.hoplite.core) implementation(libs.hoplite.yaml)