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/).