Nowadays it's normal to have multiple bank accounts, especially with apps such as Revolut becoming a huge success in Ireland. The problem my friends and I find with having multiple bank accounts is, it’s difficult to easily manage our finances. I decided to resolve this problem by designing and developing my first app called Bank Balance, which will instantly tell me my balance across multiple banks, including my savings.
The tech stack I decided on using was Expo React-Native for its cross-platform functionalities, Redux for state management and FastAPI for the Orchestration Layer. Figma was used for UI/UX prototyping. I had no previous experience using any of these technologies besides FastAPI but I’m always up for the challenge.
The initial prototype was designed using Figma and has two screens. The login screen has a single button that starts the authorisation process and upon successful authorisation, the home screen is displayed with the user's bank accounts and their corresponding balances.
Before I began App development I needed to create an Orchestration Layer using FastAPI (a modern, fast, web framework for building APIs with Python) to secure my secret keys provided by TrueLayer since apps can be reverse-engineered. Bank Balance uses TrueLayer to access users' financial data securely since TrueLayer adheres to all the Open Banking regulations. Access tokens provided after authentication are stored securely via Keychain on iOS and Keystore on Android.
The Orchestration Layer has two endpoints, /exchange and /refresh . The exchange endpoint returns an access token to the requested bank account and refresh renews the access token once it has expired. Each bank has a different threshold for how long their access tokens are valid.
By default, iPhone will block any request that is not using SSL (https://developer.apple.com/forums/thread/3544), meaning the App was prevented from making requests to the Orchestration Layer. Therefore, I generated an SSL certificate to provide the layer using mkcert, a simple tool for making locally-trusted development certificates.
It's important to retrieve and create the SSL certificate for your IPv4 Address because that's the IP address the App will use to access the Orchestration Layer. Additionally, the mkcert root certificate needs to be installed and trusted. The cert can be located by running mkcert -CAROOT .
After the Orchestration Layer was deployed I implemented logic to communicate with True Layers APIs and the Orchestration Layer. Using createSlice a function provided by the @reduxjs/toolkit library, I created two reducers, token and account . createSlice hides some of Redux’s complexity and removes boilerplate code. The token reducer is responsible for handling tokens provided by the orchestration layer and account is responsible for handling account information such as bank balance.
The fetchAccessToken function uses createAsyncThunk to return a thunk action creator meaning “a piece of code that does some delayed work” wrapped in a promise, enabling chaining through the use of .then(). The token reducer uses the expo-secure-store library to securely store token information and the account reducer uses the@react-native-async-storage/async-storage library to store account information.
Implementing the logic screen was rather difficult because Expo’s authentication library expo-auth-session would not trigger its linking callback once redirected by the testing TrueLayer environment (it would trigger in the sandbox TrueLayer environment since the app never opened another app i.e. Revolut). Therefore, I created a customisable authorisation component with callback linking functionality.
The CSS style is passed into the authorisation component via the prop buttonStyle and its children are also rendered. For example, the login screen utilises the authorisation component like so:
The home screen was the last to implement. I decided to give the initial prototype a slight revamp to look more like a balance sheet. Displaying the relevant accounts required the chaining of API requests and transforming. The API chaining worked as follows, for each access token (bank account), retrieve the permitted accounts and for each permitted account retrieve its bank balance. Then, merge each bank account with its relevant bank balance and transform the required information i.e. convert balances into local currency.
Up until now the user only had the option to link one bank account via the login screen. I added a plus button to the top right corner that implements the authorisation used previously for the login screen, reusing functionality, adhering to the DRY (do not repeat yourself) software development principle, and saving development time but increasing complexity slightly.
You can view a video demonstration here.
To conclude, this project was a lot of fun but I decided not to deploy it because of the costs involved (Apple Developer Program Fee and Orchestration Layer API fees). I had additional ideas/features for the next iteration which were:
Remove a linked bank account.
Insights such as daily spending across accounts, forecasted spending, etc.
Link multiple bank accounts upon initial login.
Working with all these new technologies was a lot of fun but I would use Typescript for future apps since code readability and maintainability was a concern as the code base grew. Older code examples of Redux had a lot of repetitive code but the @reduxjs/toolkit library removes a significant amount of it. I found Redux to be overkill for this app and unnecessary complexity but if I were to continue with development it would become extremely beneficial since passing props to children would become a nightmare to maintain. Lastly, I found Expo to be a great solution for rapid development on both mobile platforms IOS/Android.