diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/api/ExchangeApiController.java b/src/main/java/nl/andrewl/coyotecredit/ctl/api/ExchangeApiController.java
index 7356432..358d533 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/api/ExchangeApiController.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/api/ExchangeApiController.java
@@ -1,7 +1,10 @@
package nl.andrewl.coyotecredit.ctl.api;
import lombok.RequiredArgsConstructor;
+import nl.andrewl.coyotecredit.ctl.exchange.dto.PublicAccountData;
+import nl.andrewl.coyotecredit.model.User;
import nl.andrewl.coyotecredit.service.ExchangeService;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -16,7 +19,12 @@ public class ExchangeApiController {
private final ExchangeService exchangeService;
@GetMapping(path = "/tradeables")
- public Map getCurrentTradeables(@PathVariable long exchangeId) {
- return exchangeService.getCurrentTradeables(exchangeId);
+ public Map getCurrentTradeables(@PathVariable long exchangeId, @AuthenticationPrincipal User user) {
+ return exchangeService.getCurrentTradeables(exchangeId, user);
+ }
+
+ @GetMapping(path = "/accounts/{number}")
+ public PublicAccountData getAccountData(@PathVariable long exchangeId, @PathVariable String number, @AuthenticationPrincipal User user) {
+ return exchangeService.getPublicAccountData(exchangeId, number, user);
}
}
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/AccountPage.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/AccountPage.java
similarity index 91%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/AccountPage.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/AccountPage.java
index 9696ea5..506f472 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/AccountPage.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/AccountPage.java
@@ -1,7 +1,7 @@
-package nl.andrewl.coyotecredit.ctl;
+package nl.andrewl.coyotecredit.ctl.exchange;
import lombok.RequiredArgsConstructor;
-import nl.andrewl.coyotecredit.ctl.dto.TransferPayload;
+import nl.andrewl.coyotecredit.ctl.exchange.dto.TransferPayload;
import nl.andrewl.coyotecredit.model.User;
import nl.andrewl.coyotecredit.service.AccountService;
import org.springframework.http.HttpStatus;
@@ -45,7 +45,7 @@ public class AccountPage {
@GetMapping(path = "/transfer")
public String getTransferPage(Model model, @PathVariable long accountId, @AuthenticationPrincipal User user) {
- model.addAttribute("balances", accountService.getTransferData(accountId, user));
+ model.addAttribute("data", accountService.getTransferData(accountId, user));
return "account/transfer";
}
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/TradePage.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/TradePage.java
similarity index 89%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/TradePage.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/TradePage.java
index e29372a..ae37323 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/TradePage.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/TradePage.java
@@ -1,7 +1,7 @@
-package nl.andrewl.coyotecredit.ctl;
+package nl.andrewl.coyotecredit.ctl.exchange;
import lombok.RequiredArgsConstructor;
-import nl.andrewl.coyotecredit.ctl.dto.TradePayload;
+import nl.andrewl.coyotecredit.ctl.exchange.dto.TradePayload;
import nl.andrewl.coyotecredit.model.User;
import nl.andrewl.coyotecredit.service.ExchangeService;
import nl.andrewl.coyotecredit.service.TradeService;
@@ -26,7 +26,7 @@ public class TradePage {
@AuthenticationPrincipal User user
) {
model.addAttribute("data", tradeService.getTradeData(accountId, user));
- return "trade";
+ return "account/trade";
}
@PostMapping
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/BalanceData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/BalanceData.java
similarity index 63%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/BalanceData.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/BalanceData.java
index c3ec7b0..773efda 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/BalanceData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/BalanceData.java
@@ -1,4 +1,4 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
public record BalanceData(
long id,
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/ExchangeAccountData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/ExchangeAccountData.java
index b33f7a6..f67c066 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/ExchangeAccountData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/ExchangeAccountData.java
@@ -1,7 +1,5 @@
package nl.andrewl.coyotecredit.ctl.exchange.dto;
-import nl.andrewl.coyotecredit.ctl.dto.SimpleAccountData;
-
public record ExchangeAccountData(
ExchangeData exchange,
SimpleAccountData account
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/FullAccountData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/FullAccountData.java
similarity index 83%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/FullAccountData.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/FullAccountData.java
index 37ce7cb..9eeb86e 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/FullAccountData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/FullAccountData.java
@@ -1,6 +1,4 @@
-package nl.andrewl.coyotecredit.ctl.dto;
-
-import nl.andrewl.coyotecredit.ctl.exchange.dto.ExchangeData;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
import java.util.List;
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/PublicAccountData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/PublicAccountData.java
new file mode 100644
index 0000000..f923e4d
--- /dev/null
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/PublicAccountData.java
@@ -0,0 +1,10 @@
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
+
+/**
+ * Account data that can be publicly seen by any member of an exchange.
+ */
+public record PublicAccountData(
+ long id,
+ String number,
+ String name
+) {}
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/SimpleAccountData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/SimpleAccountData.java
similarity index 73%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/SimpleAccountData.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/SimpleAccountData.java
index 3a54c8a..ee5c692 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/SimpleAccountData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/SimpleAccountData.java
@@ -1,4 +1,4 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
public record SimpleAccountData (
long id,
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TradeData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TradeData.java
similarity index 73%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/TradeData.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TradeData.java
index 434fc9e..2d33158 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TradeData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TradeData.java
@@ -1,4 +1,6 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
+
+import nl.andrewl.coyotecredit.ctl.dto.TradeableData;
import java.math.BigDecimal;
import java.util.List;
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TradePayload.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TradePayload.java
similarity index 93%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/TradePayload.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TradePayload.java
index 0e1d0f8..c8c1f83 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TradePayload.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TradePayload.java
@@ -1,4 +1,4 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
/**
* The payload that's sent when a user performs a trade with the market. This
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransactionData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransactionData.java
similarity index 84%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransactionData.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransactionData.java
index d8bca50..cba86a9 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransactionData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransactionData.java
@@ -1,5 +1,6 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
+import nl.andrewl.coyotecredit.ctl.dto.TradeableData;
import nl.andrewl.coyotecredit.model.Transaction;
import java.time.format.DateTimeFormatter;
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransferData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferData.java
similarity index 84%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransferData.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferData.java
index 7b4b9b3..ccbf4ac 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransferData.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferData.java
@@ -1,5 +1,6 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
+import nl.andrewl.coyotecredit.ctl.dto.TradeableData;
import nl.andrewl.coyotecredit.model.Transfer;
import java.time.format.DateTimeFormatter;
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferPageData.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferPageData.java
new file mode 100644
index 0000000..8e4bf8b
--- /dev/null
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferPageData.java
@@ -0,0 +1,9 @@
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
+
+import java.util.List;
+
+public record TransferPageData(
+ long exchangeId,
+ List balances
+) {
+}
diff --git a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransferPayload.java b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferPayload.java
similarity index 70%
rename from src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransferPayload.java
rename to src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferPayload.java
index ac7a16e..36b7582 100644
--- a/src/main/java/nl/andrewl/coyotecredit/ctl/dto/TransferPayload.java
+++ b/src/main/java/nl/andrewl/coyotecredit/ctl/exchange/dto/TransferPayload.java
@@ -1,4 +1,4 @@
-package nl.andrewl.coyotecredit.ctl.dto;
+package nl.andrewl.coyotecredit.ctl.exchange.dto;
public record TransferPayload (
String recipientNumber,
diff --git a/src/main/java/nl/andrewl/coyotecredit/dao/AccountRepository.java b/src/main/java/nl/andrewl/coyotecredit/dao/AccountRepository.java
index 9ffee97..4eab4e8 100644
--- a/src/main/java/nl/andrewl/coyotecredit/dao/AccountRepository.java
+++ b/src/main/java/nl/andrewl/coyotecredit/dao/AccountRepository.java
@@ -14,6 +14,7 @@ public interface AccountRepository extends JpaRepository {
List findAllByUser(User user);
Optional findByNumber(String number);
Optional findByUserAndExchange(User user, Exchange exchange);
+ Optional findByNumberAndExchange(String number, Exchange exchange);
boolean existsByUserAndExchange(User user, Exchange exchange);
List findAllByExchange(Exchange e);
diff --git a/src/main/java/nl/andrewl/coyotecredit/service/AccountService.java b/src/main/java/nl/andrewl/coyotecredit/service/AccountService.java
index b39fec6..aa5b972 100644
--- a/src/main/java/nl/andrewl/coyotecredit/service/AccountService.java
+++ b/src/main/java/nl/andrewl/coyotecredit/service/AccountService.java
@@ -2,7 +2,7 @@ package nl.andrewl.coyotecredit.service;
import lombok.RequiredArgsConstructor;
import nl.andrewl.coyotecredit.ctl.dto.*;
-import nl.andrewl.coyotecredit.ctl.exchange.dto.ExchangeData;
+import nl.andrewl.coyotecredit.ctl.exchange.dto.*;
import nl.andrewl.coyotecredit.dao.*;
import nl.andrewl.coyotecredit.model.*;
import nl.andrewl.coyotecredit.util.AccountNumberUtils;
@@ -34,13 +34,13 @@ public class AccountService {
private final UserNotificationRepository notificationRepository;
@Transactional(readOnly = true)
- public List getTransferData(long accountId, User user) {
+ public TransferPageData getTransferData(long accountId, User user) {
Account account = accountRepository.findById(accountId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
if (!account.getUser().getId().equals(user.getId())) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
- return account.getBalances().stream()
+ List balances = account.getBalances().stream()
.filter(b -> b.getAmount().compareTo(BigDecimal.ZERO) > 0)
.map(b -> new BalanceData(
b.getTradeable().getId(),
@@ -50,6 +50,7 @@ public class AccountService {
))
.sorted(Comparator.comparing(BalanceData::symbol))
.toList();
+ return new TransferPageData(account.getExchange().getId(), balances);
}
@Transactional
diff --git a/src/main/java/nl/andrewl/coyotecredit/service/ExchangeService.java b/src/main/java/nl/andrewl/coyotecredit/service/ExchangeService.java
index 78ede28..9c9103a 100644
--- a/src/main/java/nl/andrewl/coyotecredit/service/ExchangeService.java
+++ b/src/main/java/nl/andrewl/coyotecredit/service/ExchangeService.java
@@ -103,6 +103,18 @@ public class ExchangeService {
.toList();
}
+ @Transactional(readOnly = true)
+ public PublicAccountData getPublicAccountData(long exchangeId, String number, User user) {
+ Exchange exchange = exchangeRepository.findById(exchangeId)
+ .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
+ if (!accountRepository.existsByUserAndExchange(user, exchange)) {
+ throw new ResponseStatusException(HttpStatus.NOT_FOUND);
+ }
+ Account account = accountRepository.findByNumberAndExchange(number, exchange)
+ .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
+ return new PublicAccountData(account.getId(), account.getNumber(), account.getName());
+ }
+
@Transactional(readOnly = true)
public void ensureAdminAccount(long exchangeId, User user) {
getExchangeIfAdmin(exchangeId, user);
@@ -168,9 +180,12 @@ public class ExchangeService {
}
@Transactional(readOnly = true)
- public Map getCurrentTradeables(long exchangeId) {
+ public Map getCurrentTradeables(long exchangeId, User user) {
Exchange e = exchangeRepository.findById(exchangeId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
+ if (!accountRepository.existsByUserAndExchange(user, e)) {
+ throw new ResponseStatusException(HttpStatus.NOT_FOUND);
+ }
Map tradeables = new HashMap<>();
for (var t : e.getAllTradeables()) {
tradeables.put(t.getId(), t.getMarketPriceUsd().toPlainString());
diff --git a/src/main/java/nl/andrewl/coyotecredit/service/TradeService.java b/src/main/java/nl/andrewl/coyotecredit/service/TradeService.java
index 37cff7f..083d187 100644
--- a/src/main/java/nl/andrewl/coyotecredit/service/TradeService.java
+++ b/src/main/java/nl/andrewl/coyotecredit/service/TradeService.java
@@ -1,7 +1,7 @@
package nl.andrewl.coyotecredit.service;
import lombok.RequiredArgsConstructor;
-import nl.andrewl.coyotecredit.ctl.dto.TradeData;
+import nl.andrewl.coyotecredit.ctl.exchange.dto.TradeData;
import nl.andrewl.coyotecredit.ctl.dto.TradeableData;
import nl.andrewl.coyotecredit.dao.AccountRepository;
import nl.andrewl.coyotecredit.model.Account;
diff --git a/src/main/java/nl/andrewl/coyotecredit/service/TradeableUpdateService.java b/src/main/java/nl/andrewl/coyotecredit/service/TradeableUpdateService.java
index b87eb9c..e98c531 100644
--- a/src/main/java/nl/andrewl/coyotecredit/service/TradeableUpdateService.java
+++ b/src/main/java/nl/andrewl/coyotecredit/service/TradeableUpdateService.java
@@ -9,6 +9,7 @@ import nl.andrewl.coyotecredit.dao.TradeableRepository;
import nl.andrewl.coyotecredit.model.Tradeable;
import nl.andrewl.coyotecredit.model.TradeableType;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -32,6 +33,7 @@ import java.util.concurrent.TimeUnit;
@Slf4j
public class TradeableUpdateService {
private final TradeableRepository tradeableRepository;
+ private final Environment environment;
private final HttpClient httpClient = HttpClient.newHttpClient();
private final ObjectMapper objectMapper = new ObjectMapper();
@@ -57,7 +59,11 @@ public class TradeableUpdateService {
for (var tradeable : publicTradeables) {
// Special case of ignoring USD as the universal transfer currency.
if (tradeable.getSymbol().equals("USD")) continue;
- executorService.schedule(() -> updateTradeable(tradeable), delay, TimeUnit.SECONDS);
+ if (environment.getProperty("coyote-credit.enable-tradeable-updates", Boolean.TYPE, true)) {
+ executorService.schedule(() -> updateTradeable(tradeable), delay, TimeUnit.SECONDS);
+ } else {
+ log.info("Tradeable update skipped for {}.", tradeable.getSymbol());
+ }
delay += POLYGON_API_TIMEOUT;
}
}
diff --git a/src/main/resources/application-development.properties b/src/main/resources/application-development.properties
index f7edcc9..e033f73 100644
--- a/src/main/resources/application-development.properties
+++ b/src/main/resources/application-development.properties
@@ -10,3 +10,4 @@ spring.mail.host=127.0.0.1
spring.mail.port=1025
coyote-credit.base-url=http://localhost:8080
+coyote-credit.enable-tradeable-updates=false
diff --git a/src/main/resources/static/js/transfer.js b/src/main/resources/static/js/transfer.js
index 84d0daf..2051a23 100644
--- a/src/main/resources/static/js/transfer.js
+++ b/src/main/resources/static/js/transfer.js
@@ -1,7 +1,14 @@
const tradeableSelect = document.getElementById("tradeableSelect");
const valueInput = document.getElementById("amountInput");
+const recipientNumberInput = document.getElementById("recipientNumberInput");
+const recipientNumberNote = document.getElementById("recipientNumberNote");
+
+const exchangeId = document.getElementById("exchangeIdInput").value;
+const accountNumberRegex = new RegExp("\\d{4}-\\d{4}-\\d{4}-\\d{4}");
tradeableSelect.addEventListener("change", onSelectChanged);
+recipientNumberInput.addEventListener("change", onAccountNumberChanged);
+recipientNumberInput.addEventListener("keyup", onAccountNumberChanged);
function onSelectChanged() {
valueInput.value = null;
@@ -17,3 +24,52 @@ function onSelectChanged() {
valueInput.setAttribute("min", 0.0000000001);
}
}
+
+/**
+ * Check that the account number that was entered is valid.
+ */
+function onAccountNumberChanged() {
+ const currentNumber = recipientNumberInput.value;
+ console.log("Account number changed to " + currentNumber);
+ if (currentNumber !== undefined && currentNumber.length > 0) {
+ if (accountNumberRegex.test(currentNumber)) {
+ recipientNumberNote.innerText = "Valid account number.";
+ fetch("/api/exchanges/" + exchangeId + "/accounts/" + currentNumber)
+ .then(response => {
+ if (response.status === 200) {
+ response.json()
+ .then(data => {
+ console.log(data);
+ showRecipientNumberNote("info", "Account number is valid. Will transfer to " + data.name + "");
+ })
+ .catch(() => {
+ showRecipientNumberNote("warning", "Could not find an account with that number.");
+ });
+ } else if (response.status === 404) {
+ showRecipientNumberNote("warning", "Could not find an account with that number.");
+ } else {
+ showRecipientNumberNote("warning", "Error: Couldn't read API response.");
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ showRecipientNumberNote("warning", "API error occurred. Couldn't fetch account information.");
+ });
+ } else {
+ showRecipientNumberNote("warning", "Invalid account number. Format: 1234-1234-1234-1234");
+ }
+ } else {
+ showRecipientNumberNote("info", "Enter an account number.");
+ }
+}
+
+function showRecipientNumberNote(type, text) {
+ recipientNumberNote.innerHTML = text;
+ if (type === "warning") {
+ recipientNumberNote.classList.add("text-danger");
+ recipientNumberNote.classList.remove("text-muted");
+ } else {
+ recipientNumberNote.classList.remove("text-danger");
+ recipientNumberNote.classList.add("text-muted");
+ }
+}
diff --git a/src/main/resources/templates/trade.html b/src/main/resources/templates/account/trade.html
similarity index 100%
rename from src/main/resources/templates/trade.html
rename to src/main/resources/templates/account/trade.html
diff --git a/src/main/resources/templates/account/transfer.html b/src/main/resources/templates/account/transfer.html
index a402028..2f30ce8 100644
--- a/src/main/resources/templates/account/transfer.html
+++ b/src/main/resources/templates/account/transfer.html
@@ -10,11 +10,12 @@
Transfer funds to other accounts.