{"id":22385214,"url":"https://github.com/marstr/envelopes","last_synced_at":"2025-06-23T17:08:31.249Z","repository":{"id":37549890,"uuid":"106078776","full_name":"marstr/envelopes","owner":"marstr","description":"A collection of Go packages to express Budget calculations and state easily.","archived":false,"fork":false,"pushed_at":"2024-01-15T22:10:31.000Z","size":3580,"stargazers_count":6,"open_issues_count":4,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-03-15T13:35:17.226Z","etag":null,"topics":["budgeting","currency","personal-finance","stocks"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marstr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-10-07T07:15:44.000Z","updated_at":"2023-04-14T23:20:16.000Z","dependencies_parsed_at":"2024-01-15T11:51:30.488Z","dependency_job_id":"8140dfed-c915-454c-ba08-962f35e30df5","html_url":"https://github.com/marstr/envelopes","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marstr%2Fenvelopes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marstr%2Fenvelopes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marstr%2Fenvelopes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marstr%2Fenvelopes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marstr","download_url":"https://codeload.github.com/marstr/envelopes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228216427,"owners_count":17886558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["budgeting","currency","personal-finance","stocks"],"created_at":"2024-12-05T01:22:13.337Z","updated_at":"2024-12-05T01:22:14.032Z","avatar_url":"https://github.com/marstr.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003ca href=\"./README.md#logo\"\u003e\u003cimg src=\"https://github.com/ashleymcnamara/gophers/raw/4ddd92f3f0830f5d9a9eab50c410878249fe6515/NERDY.png\" width=\"360\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n# envelopes\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/marstr/envelopes)](https://pkg.go.dev/github.com/marstr/envelopes)\n[![Build](https://github.com/marstr/envelopes/actions/workflows/build.yml/badge.svg)](https://github.com/marstr/envelopes/actions/workflows/build.yml)\n[![CodeQL](https://github.com/marstr/envelopes/workflows/CodeQL/badge.svg)](https://github.com/marstr/envelopes/actions?query=workflow%3ACodeQL)\n\nBeen scouring the internet looking for a personal finance library written in Go? Having trouble finding one flexible \nenough to model your budget? You have arrived at a library that aims to give you the building blocks to represent your \nfinances no matter how you look at them.\n\n## include\nWhether you're using Go modules or $GOPATH, you can acquire this library by simply running the following command from \nthe root directory of your project:\n\n``` bash\n$ go get github.com/marstr/envelopes\n```\n\n## model overview\n\n### balances\n\nThe [`Balance`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Balance) type represents an amount of funds\navailable.\n\nLet's say you're working in Euros, you could initialize a balance of €10,76 the following way:\n\n``` Go\nmySimpleBalance := envelopes.Balance{\n    \"EUR\": big.NewRat(1076, 100),\n}\n```\n\nYou'll notice above that `Balance` isn't a scalar type, but rather a dictionary. This is so accounts which hold multiple\ntypes of assets (like brokerage accounts) can have their contents fully represented. For instance, what if you need to\nrepresent the balance of a brokerage account that has 90 shares of T-Mobile (TMUS), and 89.143 shares of Tesla (TSLA)?\n \n``` Go\nmyComplexBalance := envelopes.Balance{\n    \"TSLA\": big.NewRat(89143, 1000),\n    \"TMUS\": big.NewRat(90, 1),\n}\n```\n\nWhen you do arithmetic with balances, each term will be combined with like terms. That is to say, when you [`Add`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Balance.Add)\nor [`Sub`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Balance.Sub) balances, the `\"EUR\"` component of one \nbalance will be summed against the other balance's `\"EUR\"` component, etc. Notably, because different stocks and \ncurrencies have different values, greater than and less than operations can't be done directly on instances of `\nBalance`. You'll need to [`Normalize`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Balance.Normalize) them \nfirst.\n\nWhile not all modern currencies in the world are decimalized, even the exceptions are subdivided only once; by a factor \nof five. The two exceptions are the [Malagasy ariary](https://en.wikipedia.org/wiki/Malagasy_ariary) and the \n[Mauritanian ouguiya](https://en.wikipedia.org/wiki/Mauritanian_ouguiya)). So at the time of writing, this library \nshould work reasonably well for any currency.\n\n### accounts\n\nThe [`Accounts`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Accounts) type seeks to help answer the question\n\"Where is my money?\" It is a collection of account names to the [Balance](#balances) in each account. Accounts are flat,\nand do not contain other accounts. For accounts like bank accounts and brokerage accounts, which hold assets, the\nmagnitudes should be positive. For accounts like credit cards, which hold liabilities, the intention is to have balances\nbe negative. In this regard, the sum of the balances of your accounts should be the total of your tracked value. As you \nspend money (be that on a credit card, or with a debit card) the total goes down. This is a little simpler than \ntraditional doubly-entry accounting, which has credits/debits get swapped based on the type of the account. \n\n### budgets\n\nThe [`Budget`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Budget) type seeks to help answer the question\n\"How do I want to spend my money?\" Unlike [accounts](#accounts), Budgets can be nested (a budget can live inside another\nbudget.). Because they can be nested, they have both an immediate balance and a recursive balance, which is the sum of \nits balance and all the balances of its children. The system is designed to use both accounts and budgets at the same \ntime, as we'll discuss in [#states](#states). \n\n### states\n\nA [`State`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#State) combines all your account balances with a root\nbudget. This reinforces the way the fundamental abstraction that is alluded to in the [#accounts](#accounts) and \n[#balances](#balances) sections above. A state allows you to separate the \"where\" and the \"for what\" of you money. The\nidea here is that you may want to have more control than \"all of my stocks are being saved for a down payment\", or\n\"the money in this savings account is my emergency budget.\"\n\n### transactions\n\nA [`Transaction`](https://pkg.go.dev/github.com/marstr/envelopes?tab=doc#Transaction) captures metadata around a change \nin the current `State`. It could be associated with a financial institution, or it may just capture funds being \ntransferred between two budgets. This library was inspired by [Git](https://git-scm.com), and borrows a lot its \narchitecture and ideas. One of the most notable consequences is that instead of using amount of a transaction to figure\nout the current state, it uses the current state (and the one immediately proceeding it) to figure out the amount of\nthe transaction.\n\n### immutability\n\nConceptually, each of the models above are immutable. A SHA1 uniquely identifies each one so that it can be stored to\ndisk and referred to later unambiguously. This immutability has not made its way into the code, however. This allows\nobjects to be built up and modified more easily between being committed to disk.\n\n## related projects\n\n### baronial\n[baronial](https://github.com/marstr/baronial/tree/main/README.md) is a command line interface that exposes the \nconcepts enumerated above in a way that is ready to be scripted against, or just interacted with by a person comfortable\nworking in a terminal.\n\n### envelopes-azure\n\n[envelopes-azure](https://github.com/marstr/envelopes-azure/tree/master/README.md) implements a client for storing\nserialized `IDer`s in Azure, instead of just using filesystem constructs.\n\n## logo\n\nThe nerdy gopher is artwork by the amazing Ashley Willis (McNamara), and is based on the gopher drawn by Renée French. It is \nlicensed under the [\nAttribution-NonCommercial-ShareAlike 4.0 International](https://github.com/ashleymcnamara/gophers/blob/4ddd92f3f0830f5d9a9eab50c410878249fe6515/LICENSE)\nLicense. You can find this gopher, and many more like it, at: https://github.com/ashleymcnamara/gophers \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarstr%2Fenvelopes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarstr%2Fenvelopes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarstr%2Fenvelopes/lists"}