usawa

Signed, immutable accounting.
Log | Files | Refs | Submodules | LICENSE

README (11254B)


      1 # Usawa
      2 
      3 A local-first, authenticated and immutable accounting schema for individuals and small businesses.
      4 
      5 This readme will only guide you to run some example commands, without giving you much insight.
      6 
      7 Please refer to the documentation in `doc/`. If is vanilla [GNU Texinfo](https://www.gnu.org/software/texinfo/), and can easily be built with:
      8 
      9 ```
     10 cd doc/
     11 makeinfo --html index.texi
     12 ``` 
     13 
     14 The HTML entry point for local browsing will be in `doc/index_html/index.html`
     15 
     16 
     17 ## Dependencies
     18 
     19 OS dependencies upon which python dependencies rely:
     20 
     21 * [libsodium](https://libsodium.net/)
     22 * [valkey](https://valkey.io/) (server running)
     23 
     24 Note that `valkey` is implemented for the POC, but even this POC library allows for any key-value store that satisfies the [whee](https://pypi.org/project/wheepy/) interface.
     25 
     26 ## Build
     27 
     28 ```
     29 git submodule update --init
     30 python -mvenv .venv
     31 . .venv/bin/activate
     32 cd dummy
     33 pip install .
     34 ```
     35 
     36 You can verify the setup by running the tests:
     37 
     38 `find tests/ -iname "*.py" -exec python {} \;`
     39 
     40 
     41 ## Trying out the tools
     42 
     43 
     44 ### Creating a ledger
     45 
     46 The topic may be any value, and will be stored under its digest. Prefix with `0x` to define a literal hexadecimal value.
     47 
     48 `python usawa/runnable/create.py -t <sometopic> -o start.xml`
     49 
     50 Once completed, the contents of `start.xml` will be something like this:
     51 
     52 
     53 ```
     54 <?xml version="1.0"?>
     55 <ledger xmlns="http://usawa.defalsify.org/" version="1">
     56   <topic xmlns:ns="http://usawa.defalsify.org/">7092e69f8179a45f673f8e4b85cf7de2a09d5f3e43f801fd2c1a47c6dcd9f14a0137c7a1244e7e625057850f3e0c4132bbd23877c2ede5f49f12e646bb5cca7b</topic>
     57   <generated xmlns:ns="http://usawa.defalsify.org/">2026-01-19T18:19:57Z</generated>
     58   <src xmlns:ns="http://usawa.defalsify.org/"/>
     59   <units xmlns:ns="http://usawa.defalsify.org/" base="BTC">
     60     <unit sym="BTC">
     61       <precision>2</precision>
     62       <exchange>1000000000</exchange>
     63     </unit>
     64   </units>
     65   <identity xmlns:ns="http://usawa.defalsify.org/" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" didtype="usawa"/>
     66   <incoming xmlns:ns="http://usawa.defalsify.org/" serial="0">
     67     <real unit="BTC">
     68       <asset>0</asset>
     69       <liability>0</liability>
     70     </real>
     71     <digest algo="sha512">00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</digest>
     72     <sig keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" type="ed25519">3615f40538a11d625400ac0195f803c68c7b53b93f095753dcca93c5eb2851004c2b28ca067fd6bd298e73ebe1fa02eb1392e0ff83c87a5c421516951c33c30b</sig>
     73   </incoming>
     74 </ledger>
     75 ```
     76 
     77 
     78 ### Adding a ledger entry
     79 
     80 Using the initial state of the ledger, the `add.py` tool can be used to interactively specify a new entry in the ledger.
     81 
     82 `python usawa/runnable/add.py -i start.xml -o first.xml`
     83 
     84 If correctly specified, this will store an entry in the `valkey` database, and output the new _truncated state_ (digest and serial set to last added entry) of the ledger to `first.xml`.
     85 
     86 Another entry may be added using the new _truncated state_:
     87 
     88 `python usawa/runnable/add.py -i first.xml -o second.xml`
     89 
     90 ... and so on.
     91 
     92 
     93 #### Attaching assets to entries
     94 
     95 The `add.py` tool provides the `-x` flag to add a file as an attachment to the entry. The flag can be specified several times.
     96 
     97 Although the tool will attempt to auto-detect metadata from the file, there is no support for explicitly defining file metadata in the tool currently.
     98 
     99 
    100 ### Viewing the ledger
    101 
    102 An XML representation of the ledger and its entries may be generated using the corresponding ledger state.
    103 
    104 Using states from the precending examples:
    105 
    106 ```
    107 # Will output the zero-state ledger header, aswell as two entries
    108 python usawa/runnable/view.py start.xml
    109 # Will output the ledger header after the first entry, aswell as one entry.
    110 python usawa/runnable/view.py first.xml
    111 # Will output the ledger header after the second entry with no entries.
    112 python usawa/runnable/view.py second.xml
    113 ``` 
    114 
    115 Example output of the first command:
    116 
    117 ```
    118 <?xml version="1.0"?>
    119 <ledger xmlns="http://usawa.defalsify.org/" version="1">
    120   <topic xmlns:ns="http://usawa.defalsify.org/">24448167713e4f7d7e09fd06716b17ffcbd8bd10aa2ebbaac0a0902292993a86244acb9683c7dc45500daf1193a760b87de6fadd0f7b30c1a7b63ac06c555ca8</topic>
    121   <generated xmlns:ns="http://usawa.defalsify.org/">2026-01-20T09:30:34Z</generated>
    122   <src xmlns:ns="http://usawa.defalsify.org/">defalsify.org</src>
    123   <units xmlns:ns="http://usawa.defalsify.org/" base="BTC">
    124     <unit sym="BTC">
    125       <precision>2</precision>
    126       <exchange>1000000000</exchange>
    127     </unit>
    128   </units>
    129   <identity xmlns:ns="http://usawa.defalsify.org/" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" didtype="usawa"/>
    130   <incoming xmlns:ns="http://usawa.defalsify.org/" serial="0">
    131     <real unit="BTC">
    132       <asset>0</asset>
    133       <liability>0</liability>
    134     </real>
    135     <digest algo="sha512">00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</digest>
    136   </incoming>
    137   <entry>
    138     <data>
    139       <parent>00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</parent>
    140       <ref>2ae1dae8-8071-4a40-983d-e25f80634d6b</ref>
    141       <serial>1</serial>
    142       <date>2026-01-20</date>
    143       <dateTimeRegistered>2026-01-20T09:29:28Z</dateTimeRegistered>
    144       <description>awergaergh</description>
    145       <debit type="expense">
    146         <unit>BTC</unit>
    147         <account>general</account>
    148         <amount>-2346300</amount>
    149       </debit>
    150       <credit type="asset">
    151         <unit>BTC</unit>
    152         <account>general</account>
    153         <amount>2346300</amount>
    154       </credit>
    155     </data>
    156     <sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">0a0bec86152bd411dff6d7569778305f30bf52dd03c060992d8bfd1f3432fe27cf3acd17d8019a0e5e3fe0c038664c478b1576fed027f3902bb32b56b05fd708</sig>
    157   </entry>
    158   <entry>
    159     <data>
    160       <parent>50740013c78726ddd4fd199bbe21ad3eb3c50dcfd3540e12c5b52151a9b9f3a41346a22a2d1928dfc5749faac332a8c15ff2f545e8ff92b07aa037c39b1ba93e</parent>
    161       <ref>182536c7-f2ce-4976-af2a-6b0d2cf10e0c</ref>
    162       <serial>2</serial>
    163       <date>2026-01-20</date>
    164       <dateTimeRegistered>2026-01-20T09:29:40Z</dateTimeRegistered>
    165       <description>wergagh</description>
    166       <debit type="expense">
    167         <unit>BTC</unit>
    168         <account>general</account>
    169         <amount>-1251613262700</amount>
    170       </debit>
    171       <credit type="asset">
    172         <unit>BTC</unit>
    173         <account>general</account>
    174         <amount>1251613262700</amount>
    175       </credit>
    176     </data>
    177     <sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">603bf1bf05951f1c78e3ba9ab430e914f73f03b6570c15cb241695393e57eb178029ba1ff0f86afa5f29ea10ea49418825e387feb8d03f79280593e4598b1b0d</sig>
    178   </entry>
    179 </ledger>
    180 ```
    181 
    182 Sample output of second command:
    183 
    184 ```
    185 <?xml version="1.0"?>
    186 <ledger xmlns="http://usawa.defalsify.org/" version="1">
    187   <topic xmlns:ns="http://usawa.defalsify.org/">24448167713e4f7d7e09fd06716b17ffcbd8bd10aa2ebbaac0a0902292993a86244acb9683c7dc45500daf1193a760b87de6fadd0f7b30c1a7b63ac06c555ca8</topic>
    188   <generated xmlns:ns="http://usawa.defalsify.org/">2026-01-20T09:32:09Z</generated>
    189   <src xmlns:ns="http://usawa.defalsify.org/">defalsify.org</src>
    190   <units xmlns:ns="http://usawa.defalsify.org/" base="BTC">
    191     <unit sym="BTC">
    192       <precision>2</precision>
    193       <exchange>1000000000</exchange>
    194     </unit>
    195   </units>
    196   <identity xmlns:ns="http://usawa.defalsify.org/" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" didtype="usawa"/>
    197   <incoming xmlns:ns="http://usawa.defalsify.org/" serial="1">
    198     <real unit="BTC">
    199       <asset>2346300</asset>
    200       <liability>0</liability>
    201     </real>
    202     <digest algo="sha512">50740013c78726ddd4fd199bbe21ad3eb3c50dcfd3540e12c5b52151a9b9f3a41346a22a2d1928dfc5749faac332a8c15ff2f545e8ff92b07aa037c39b1ba93e</digest>
    203   </incoming>
    204   <entry>
    205     <data>
    206       <parent>50740013c78726ddd4fd199bbe21ad3eb3c50dcfd3540e12c5b52151a9b9f3a41346a22a2d1928dfc5749faac332a8c15ff2f545e8ff92b07aa037c39b1ba93e</parent>
    207       <ref>182536c7-f2ce-4976-af2a-6b0d2cf10e0c</ref>
    208       <serial>2</serial>
    209       <date>2026-01-20</date>
    210       <dateTimeRegistered>2026-01-20T09:29:40Z</dateTimeRegistered>
    211       <description>wergagh</description>
    212       <debit type="expense">
    213         <unit>BTC</unit>
    214         <account>general</account>
    215         <amount>-1251613262700</amount>
    216       </debit>
    217       <credit type="asset">
    218         <unit>BTC</unit>
    219         <account>general</account>
    220         <amount>1251613262700</amount>
    221       </credit>
    222     </data>
    223     <sig type="ed25519" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc">603bf1bf05951f1c78e3ba9ab430e914f73f03b6570c15cb241695393e57eb178029ba1ff0f86afa5f29ea10ea49418825e387feb8d03f79280593e4598b1b0d</sig>
    224   </entry>
    225 </ledger>
    226 ```
    227 
    228 Sample output of third command:
    229 
    230 ```
    231 <?xml version="1.0"?>
    232 <ledger xmlns="http://usawa.defalsify.org/" version="1">
    233   <topic xmlns:ns="http://usawa.defalsify.org/">24448167713e4f7d7e09fd06716b17ffcbd8bd10aa2ebbaac0a0902292993a86244acb9683c7dc45500daf1193a760b87de6fadd0f7b30c1a7b63ac06c555ca8</topic>
    234   <generated xmlns:ns="http://usawa.defalsify.org/">2026-01-20T09:34:49Z</generated>
    235   <src xmlns:ns="http://usawa.defalsify.org/">defalsify.org</src>
    236   <units xmlns:ns="http://usawa.defalsify.org/" base="BTC">
    237     <unit sym="BTC">
    238       <precision>2</precision>
    239       <exchange>1000000000</exchange>
    240     </unit>
    241   </units>
    242   <identity xmlns:ns="http://usawa.defalsify.org/" keyid="3b54648d60bb8a5b9e84fa0057f79b3a5996e511682e80176dc948dcbff5a4fc" didtype="usawa"/>
    243   <incoming xmlns:ns="http://usawa.defalsify.org/" serial="2">
    244     <real unit="BTC">
    245       <asset>1251613262700</asset>
    246       <liability>0</liability>
    247     </real>
    248     <digest algo="sha512">aaaf17ff1a5866b1e43746686cd3029a5d0a08178986b3eccd8f94ad6f5e3076160f8bfb67ba2ee8c0e68fcec6f8bf3f2da2e61ef96cd5c11c0cef8043dde4df</digest>
    249   </incoming>
    250 </ledger>
    251 ```
    252 
    253 
    254 ### Exporting the ledger
    255 
    256 Entries can be exported as XML to a directory using the `usawa/runnable/export.py` command.
    257 
    258 The input to the export command is the zero-state ledger xml file.
    259 
    260 The filename of each entry written to the directory will be its sha512 hash.
    261 
    262 Each entry will produce two files, one of them containing the canonical XML for the entry, the other including entry metadata that is not part of the canonicalized data.
    263 
    264 
    265 
    266 ## State of development
    267 
    268 This software is to be considered proof-of-concept and not safe for use in production in any way.
    269 
    270 Shortcomings include:
    271 
    272 * Media assets and attachments are not yet implemented.
    273 * No PKI functions are available to manage public key lists.
    274 * A single, unencrypted private key entry in the key-value store is used for signatures.
    275 
    276 
    277 ## Legals
    278 
    279 Copyright 2026 by Louis Holbrook, all rights reserved.
    280 
    281 All software licensed under [GNU Affero General Public License 3.0](https://www.gnu.org/licenses/agpl-3.0.en.html).
    282 
    283 All documentation licensed under [Creative Commons Attribution-Sharealike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/).