API Integration Framework
- Overview The basic idea behind this PR is to integrate a framework which would enable external APIs to be integrated to generate transaction data in wealthfolio.
This PR contains the framework itself and 3 APIs.
I've done some initial testing myself and have the following to take into consideration:
-
cash balance for the
CoinbaseandBitvavoAPIs are currently not displaying properly. I think this is due to the fact that deposit data to these brokers is not provided by the endpoint thus cash is not added to the account resulting in a wrong cash balance. I do have some ideas of resolving this, but this also comes with trade-offs. -
Due to the large number of denominators often found in crypto, rounding can cause deviations in actual holding.
-
The
Trading212API works well, main issue is that when pulling large transaction history the API throws429errors. Currently this is handled using backoffs (which works well). But as a result pulling large (+3 months) of data at a time can result in long update cycles.
-
Repository Structure
src/brokers/brokers/– individual provider implementationsbroker_factory.rs– runtime instantiation by broker keybroker_provider.rs– common trait, types, and errorsbroker_service.rs– high-level sync logic and Tauri integrationencryption.rs– at-rest key encryption
-
Adding a New Broker (Also generated some documentation of how this works in the PR)
- Step 1: Create
FooProviderinsrc/brokers/brokers/foo_provider.rsuse crate::brokers::broker_provider::{BrokerApiConfig, BrokerError}; pub struct FooProvider { api_key: String, api_secret: Option<String>, client: reqwest::Client, endpoint: String, } impl FooProvider { pub async fn new(config: BrokerApiConfig) -> Result<Self, BrokerError> { let api_key = config.api_key; let api_secret = config.optional; Ok(Self { api_key, api_secret, client: reqwest::Client::new(), endpoint: "https://api.foo.com/v1/transactions".into(), }) } } - Step 2: Register in
broker_factory.rsmatch account.broker_type.as_str() { "BITVAVO" => BitvavoProvider::new(config).await, "FOO" => FooProvider::new(config).await, _ => Err(BrokerError::UnknownBroker(account.broker_type.clone())), } - Step 3: Extend frontend mapping in
src/lib/brokers.tsexport const supportedBrokers = [ { label: 'Bitvavo', value: 'BITVAVO' }, { label: 'Foo', value: 'FOO' }, ]; - Step 4: Toggle the extra-secret field in
account-form.tsxfor brokers requiring an API secret{["BITVAVO", "FOO"].includes(brokerName!) && ( <FormField name="brokerExtra" label="API Secret"> {/* … */} </FormField> )}
- Step 1: Create
My bad for the sloppy text it’s way past my bedtime! :)
If there're any questions or changes to be made let me know!
Hi @SvenHockers,
I apologize for the delay.
I have finalized version 1.2, which includes the following updates:
- Added secret management for API keys. This feature now securely stores API keys for the market data provider in the underlying platform's secure store (macOS Keychain, Windows Credential Manager, Linux: DBus-based Secret Service, and kernel keyutils).
Could you please update this PR to utilize this API?
Regarding the architecture, the platform table should contain the broker platforms (without the API key), and accounts can be linked to a platform. The table and column are already in place; you may just need to add an "enabled" column to the platform.
In the settings, we can add a section for platforms to enable and add API keys. The overall structure should be similar to the market data provider settings.
please let me know if you have time to work on this or if you prefer I fork and continue on your PR.
Thank you
Hey @afadil
I'll look at the changes that have to be made. I've had a fairly busy period so will have to see if I can manage to update this PR within reasonable time.
I will let you know!
Cheers, Sven
Hi @afadil,
I will try to get this PR updated during the weekend. Will send you an update by Monday 08/09 at the latest!
Cheers, Sven