1
0
Files
dfi-docs/markdown/How-do-I-use-it.md

354 lines
16 KiB
Markdown

[//]: # (docker-finance | modern accounting for the power-user)
[//]: # ()
[//]: # (Copyright [C] 2021-2026 Aaron Fiore [Founder, Evergreen Crypto LLC])
[//]: # ()
[//]: # (This program is free software: you can redistribute it and/or modify)
[//]: # (it under the terms of the GNU General Public License as published by)
[//]: # (the Free Software Foundation, either version 3 of the License, or)
[//]: # ([at your option] any later version.)
[//]: # ()
[//]: # (This program is distributed in the hope that it will be useful,)
[//]: # (but WITHOUT ANY WARRANTY; without even the implied warranty of)
[//]: # (MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the)
[//]: # (GNU General Public License for more details.)
[//]: # ()
[//]: # (You should have received a copy of the GNU General Public License)
[//]: # (along with this program. If not, see <https://www.gnu.org/licenses/>.)
# [<img src="../assets/branding/png/dfi.png" height=10% width=10%/>](https://gitea.evergreencrypto.co/EvergreenCrypto/docker-finance "docker-finance")
- **[How do I use it?](#how-do-i-use-it)**
* [Mostly-Unified CLI](#mostly-unified-cli)
* [Flow Layout](#flow-layout)
* [Plugins](#plugins)
* [Caveats & Oddities](#caveats--oddities)
## How do I use it?
### Mostly-Unified CLI
You'll only need the single alias `dfi` when using docker-finance on your client (host) and/or within your container.
However, this alias can be broken down into the following:
1. The client script which handles the client-side (host) system: `docker.bash` (alias `dfi`)
2. The container script which handles the container-side system: `finance.bash` (alias `dfi`)
These two scripts can be rationalized by the following format:
<script> <super/sub> <command> [args]
For example, these [Screenshots](What-does-it-do.md#screenshots) describe a setup with mockup data where the client (host) user named `business`, along with container `$DOCKER_FINANCE_USER` named `business`, engage in client/container activity. The container profile named `testprofile` and its subprofile named `testuser` can be described as `<super/sub>` portion of the format (`testprofile/testuser`).
It should be noted that, for your convenience:
- command arguments [args] can be arranged in any order
- commandline completion is available for all `dfi <super/sub> command [args]` (save your fingers and tab away!)
- For client (host), an image must first be built for completion to be available
---
#### Client (Host) Command Format
The client (host) command format consists of:
docker.bash <platform/username:tag> <command> [args]
Where:
- `docker.bash` is located in `${DOCKER_FINANCE_CLIENT_REPO}/client`
- `<platform/username:tag>`
- `platform` is the image platform (archlinux, ubuntu)
- `username` is the client (host) username with read/write permissions to the container (see [Configuration Files](How-do-I-get-started.md#configuration-files))
- `tag` is a custom tag you can use to delineate any number of images that you wish you create (`latest`, `dev`, etc.)
- `<command>` is the command to pass to `docker.bash`
- `[args]` are the (optional) arguments to pass to `<command>`
If the [Installation](How-do-I-get-started.md#installation) was successful, `docker.bash` is aliased to `docker-finance` and `dfi` (either can be used).
For a complete list of commands and usage help (`<platform/user:tag>` *not* required):
```bash
dfi help
```
To view the help usage of a specific command, for example; the `edit` command (`<platform/user:tag>` *is* required):
```bash
dfi archlinux/${USER}:default edit help
```
---
#### Container Command Format
The container command format consists of:
finance.bash <profile/subprofile> <command> [args]
Where:
- `finance.bash` is located in `${DOCKER_FINANCE_CLIENT_REPO}/container`
- `<profile/subprofile>`
- `profile` is the profile, as defined during [Environment Generation](How-do-I-get-started.md#environment-generation)
- `subprofile` is the subprofile (user), as defined during [Environment Generation](How-do-I-get-started.md#environment-generation)
- `<command>` is the command to pass to `finance.bash`
- `[args]` are the (optional) arguments to pass to `<command>`
By default, `finance.bash` is aliased to `finance` and `dfi` (either can be used).
For a complete list of commands (`<profile/subprofile>` *not* required):
```bash
dfi help
```
To view the help usage of a specific command, for example; the `fetch` command (`<profile/subprofile>` *is* required):
Assuming `<profile/subprofile>` is `testprofile/testuser`:
```bash
dfi testprofile/testuser fetch help
```
Or, use a subprofile alias, as described in [Subscript](How-do-I-get-started.md#subscript):
```bash
testuser_fetch help
```
### Flow Layout
A primary read through of [hledger](https://hledger.org) and [hledger-flow](https://github.com/apauley/hledger-flow/blob/master/README.org) documentation should bring you up to speed on most of the essentials.
As for docker-finance specifics, you can create a *test profile* during [Environment Generation](How-do-I-get-started.md#environment-generation) to see what your flow's layout should look like.
> Note: be sure to select 'y' when asked if this will be a development profile, and then go on to create account(s).
Once inside the container, assuming you created a profile named `testprofile` and subprofile named `testuser`, issue the following commands:
```bash
finance testprofile/testuser fetch all=price api=mobula year=all && finance testprofile/testuser import year=2018
```
> Note: for this *test profile* with developer mockups, you **MUST** import from `2018` as there are accounts that begin from that year
After experimenting with a *test profile*, you can re-run `gen` again to create a regular profile.
#### Profiles
All profiles/subprofiles are installed into the parent directory `${DOCKER_FINANCE_CONTAINER_FLOW}/profiles`.
Peeking inside `${DOCKER_FINANCE_CONTAINER_FLOW}/profiles/profile/subprofile`, you'll see the following:
- `all-years.journal` and `directives.journal`
- These top-level journals are generated by `hledger-flow`. Ignore these and use the container `edit` command for all journal editing.
- `conf.d`
- Location of all docker-finance configuration files (see `edit help` for details).
- `import`
- Location of all CSV data and *real* journals. This is where you'll place CSV files and custom account/subaccount changes (see `edit help` for details).
- `prices`
- Location of all market price data, by year, as acquired by `fetch price` (see `fetch help` for details).
- `reports`
- Location of all generated reports, by year, as generated by `reports` (see `reports help` for details).
- `taxes`
- Location of all generated taxes, by year, as generated by `taxes` (see `taxes help` for details).
Note:
- For manual CSV downloads, place you CSV file into your `${DOCKER_FINANCE_CONTAINER_FLOW}/profiles/profile/subprofile/import/subprofile/account/subaccount/1-in/year` directory (replacing `year` with the year of data that the file/data represents). See `import help` for details.
- When you want to edit custom settings for an account or a subaccount, use the container `edit` command. See container's `edit help` for details.
#### Times
All `times` related files will reside in `${DOCKER_FINANCE_CONTAINER_FLOW}/times` (this includes the timewarrior database).
See the container `times help` command for details.
### Plugins
Plugins (pluggables) allow you to leverage `dfi` client/container APIs, libraries and environments to meet your unique needs.
Checkout this two-part client/container set of [Bitcoin plugins](#plugins-bitcoin) to see how all APIs/libraries/environments can work together in unison.
For more information and other examples, see some of the various existing plugins (pluggables) and respective help usage, i.e.;
- Client-side (host): `dfi <platform/user:tag> plugins help`
- Container-side: `dfi <profile/subprofile> plugins help`
- Within `root` interpreter: `dfi::help()`
#### Plugins: Layout
Plugins are categorical:
1. Repository (`repo`) plugins
- These plugins remain within the repository and will require a pull request for any changes to be made to them.
2. End-user (`custom`) plugins
- These plugins remain on your client (host) and are bind-mounted to your container; allowing you to drop-in any code that you write while keeping them local and private.
Within these categories are subcategories where plugins exist either client-side (host) or container-side; meaning, they rely upon (or operate within) their respective client/container APIs/libraries/environments:
1. `client` | *Tends to operate only client-side (host) but can also utilize a container*
- `docker` | *Operates **only** from the `bash` shell*
* Called client-side with `dfi <platform/user:tag> plugins`
* Can be any language so long as:
- The file is executable by the shell
- The plugin reads the shell environment
- The plugin initializes the respective library (`lib_docker`)
2. `container` | *Operates **only** within the container*
- `finance` | *Operates **only** from the `bash` shell*
* Called container-side with `dfi <profile/subprofile> plugins`
* Can be any language so long as:
- The file is executable by the shell
- The plugin reads the shell environment
- The plugin initializes the respective library (`lib_finance`)
- `root` | *Operates **only** within the `root` interpreter*
* Called container-side by either two different ways:
- Within a running `dfi <profile/subprofile> root` instance:
* `dfi::plugin::load("repo/a_repo_plugin/plugin.cc")`
* `dfi::plugin::load("custom/my_custom_plugin/plugin.cc")`
- With the `dfi <profile/subprofile> root plugins` command
* Use tab completion to see available plugins (pluggables)
* Can only be languages supported by the interpreter (C/C++)
To mirror these categories, a client-side `custom` plugin directory layout is generated upon `dfi <platform/user:tag> gen`. This layout consists of:
1. `${DOCKER_FINANCE_CLIENT_PLUGINS}/client/docker`
- This path remains client-side only (not bind-mounted)
- This layout mirrors `repo` plugins [`client/plugins`](https://gitea.evergreencrypto.co/EvergreenCrypto/docker-finance/src/branch/master/client/plugins)
2. `${DOCKER_FINANCE_CLIENT_PLUGINS}/container/{finance,root}`
- The container directory is bind-mounted to `DOCKER_FINANCE_CONTAINER_PLUGINS`
- This layout mirrors `repo` plugins [`container/plugins`](https://gitea.evergreencrypto.co/EvergreenCrypto/docker-finance/src/branch/master/container/plugins)
**WARNING: don't change the above expected layout!** However, you can add subdirectories, e.g.;
- `${DOCKER_FINANCE_CLIENT_PLUGINS}/client/docker/my_docker_plugins/plugin.bash`
- `${DOCKER_FINANCE_CLIENT_PLUGINS}/container/finance/my_finance_plugins/plugin.bash`
- `${DOCKER_FINANCE_CLIENT_PLUGINS}/container/root/my_plugin/my_plugin.cc`
* NOTE: `root` pluggable auto-(un)loading requires a parent directory as the callable namespace (and more)
- See docs for details: `dfi dev-tools/${USER}:default doxygen gen`
#### Plugins: Bitcoin
`dfi`'s bitcoin plugin is a two-part client/container set of plugins that gives you direct access to bitcoin's libbitcoinkernel (and related headers/symbols).
The following demo assumes that you'll be using a fresh setup and that you've at least satisfied the required dependencies in [Installation](How-do-I-get-started.md#installation) (Docker Engine/Compose/Buildx, Bash, Git).
If you're a first-time user and/or developer who simply wants a quickstart, run the following before proceeding:
```bash
git clone --depth=1 https://gitea.com/EvergreenCrypto/docker-finance docker-finance/repo
./docker-finance/repo/client/install.bash && source ~/.bashrc
dfi archlinux/${USER}:default gen all=all profile=testprofile/testuser confirm=no dev=on
```
##### Plugins: Bitcoin: Client
Here, we prepare client-side dependencies and build everything needed for the container-side plugin:
<video src="../assets/examples/webm/client-plugins-bitcoin.webm" controls></video>
Shell 1:
```bash
# NOTE: editing will only be required once (unless you `gen type=build` in the future)
dfi archlinux/${USER}:default edit type=build
dfi archlinux/${USER}:default build type=default
```
Shell 2:
```bash
dfi archlinux/${USER}:default up
```
Shell 1:
```bash
dfi archlinux/${USER}:default plugins repo/bitcoin.bash get
dfi archlinux/${USER}:default plugins repo/bitcoin.bash build
```
##### Plugins: Bitcoin: Container
Here, we see the multiple ways the container-side plugin can be loaded and also test its functionality:
<video src="../assets/examples/webm/container-root-plugins-bitcoin_cli.webm" controls></video>
Shell 2 (or open a new shell into container, as seen in the demo):
```bash
dfi testprofile/testuser root
```
Within `root` interpreter:
```cpp
// NOTE:
// - The demo shows `btck` tab completion (which can't be put here)
// - semicolons are not needed, since the following is executed per line
GetRandHash()
dfi::plugin::load("repo/bitcoin/bitcoin.cc")
GetRandHash()
dfi::macro::load("repo/test/unit.C", "Random*")
.quit
```
Shell 2:
```bash
BENCHMARK_FILTER="^Random" dfi testprofile/testuser root plugins/repo/bitcoin/bitcoin.cc 'dfi::macro::load(\"repo/test/benchmark.C\"); dfi::common::exit(0);'
dfi testprofile/testuser root plugins/repo/bitcoin/bitcoin.cc 'dfi::macro::load(\"repo/web/server.C\")'
```
##### Plugins: Bitcoin: Web browser
Here, we see a real-world visualization of what the container-side plugin can produce. In this example, with the plugin previously loaded (as seen above), we sample bitcoin's RNG:
<video src="../assets/examples/webm/container-root-plugins-bitcoin_web.webm" controls></video>
- Open browser to `http://127.0.0.1:8080`
* Default port can be changed with client-side command: `dfi archlinux/${USER}:default edit type=env`
- Click `rng_sample` -> Enter sample amount
- Click `reload`
### Caveats & Oddities
#### Caveats & Oddities: Flow
Your `flow` directory will contain a symlink called `src` which links to code that processes your data. **Do not delete this symlink**.
##### Caveats & Oddities: Flow: Prices
Before you try to infer market prices, be sure to fetch prices *before* you do your first import (or first import of the year). If you do not fetch, the prices journal will **not** be included within the import and, if you have a previous year of prices, **you will unwittingly infer against that previous year instead of your expected year!**
##### Caveats & Oddities: Flow: Accounts: Trezor
In the "Trezor Suite" app, change your wallet name to your subaccount(s). For example, to delineate between your Trezor One from several Trezor T devices, and to delineate between their separate wallets *within* every device, follow these steps:
Example, using your #2 Trezor T device and one of its BTC "storage" wallets:
1. Change wallet name in app to `t-2:storage-1` as it's your Trezor T device #2, 1st bitcoin wallet named `storage-1` (versus your 2nd bitcoin wallet named `storage-2`, etc.)
2. Export the CSV file to the appropriate directory. It will be in the format of `t_2_storage_1_20230629T230013.csv` (timestamp will be different)
3. Rename the file to `t-2:storage-1_BTC.csv` (be sure to append the currency ticker to the file. So, `_BTC` if bitcoin or `_LTC` if litecoin, etc).
> Note: see Trezor `mockup` data within the docker-finance repository for a working example.
docker-finance relies on `Amount unit` within the file for the actual symbol/currency so, this file naming convention serves at least two purposes:
1. This allows you to maintain device continuity by reusing wallet names for different currencies.
2. This allows you to export, in the future, to the correct file from the associated hardware wallet because each hardware wallet exports its own unique CSV.
##### Caveats & Oddities: Flow: Taxes
- If you have a wallets designated for `SPEND`ing/`GIFT`ing or `INCOME`, you can use custom rules to mark all outgoing/incoming transactions as such (ex., using tags `taxed_as:SPEND`/`taxed_as:GIFT`/`taxed_as:INCOME`/etc.). See implementation for details.
- **WARNING**: *all* `GIFTIN` cost-basis must be manually entered from the corresponding `GIFT` results/calculations (as gifted from another).
- For blockchain-related transactions, you can easily add cost-basis of a gift received (`GIFTIN`) by TXID in your custom rules
- Example: despite Electrum providing `fiat_value`, you'll need to manually enter in your custom rules the correct `GIFT` value (if divergent)
[//]: # (vim: sw=2 sts=2 si ai et)