
Show HN: An API to store balances and transactions - andriosr
Hey everyone!<p>I&#x27;m Rob and I want to share what I&#x27;ve built - a solid ledger behind simple API: <a href="https:&#x2F;&#x2F;decimals.app" rel="nofollow">https:&#x2F;&#x2F;decimals.app</a><p>The ledger is a key piece of any financial system and is easy to get the design wrong, resulting in troubles for making sure money movements are adding up.<p>I took a lot of inspiration from good designs from Square, Uber, and others for the scalability and security aspects. And on the usability side, I applied many concepts from the Ledger CLI, making it very easy to use.<p>I&#x27;m really happy I get to show this to you all, thank you for reading about it! Please let me know your thoughts and questions in the comments (The sample code on the landing page is not working, I&#x27;m fixing it).<p>[1] <a href="https:&#x2F;&#x2F;www.ledger-cli.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.ledger-cli.org&#x2F;</a><p>[2] <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=iN6mhI5hFt4" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=iN6mhI5hFt4</a><p>[3] <a href="https:&#x2F;&#x2F;developer.squareup.com&#x2F;blog&#x2F;books-an-immutable-double-entry-accounting-database-service&#x2F;" rel="nofollow">https:&#x2F;&#x2F;developer.squareup.com&#x2F;blog&#x2F;books-an-immutable-doubl...</a><p>[5] <a href="https:&#x2F;&#x2F;docs.decimals.app" rel="nofollow">https:&#x2F;&#x2F;docs.decimals.app</a>
======
joshuakelly
I actually pitched this exact idea to YC and was part of W20 - but I very
quickly pivoted away from it.

If anyone is wondering about this, the basic business challenge you have to
solve is being in the right place at the right time. This kind of thing is
very sticky once its in place, and most startups don't realize the complexity
in the domain early enough for a stand-alone service to make sense to them.

I think as far as startups in this space go, the best path forward would be to
nurture an open source project in the long term.

I ended up open sourcing my work after the pivot here:
[https://github.com/affiga/scaledger](https://github.com/affiga/scaledger)

~~~
andriosr
Interesting! I would love to talk to you about the experience, can we have
have a quick chat?

~~~
joshuakelly
Yep, email in profile

------
canterburry
We pretty much use a private blockchain for the very same purpose.

Its internal, only our systems have access, each user/customer is auto created
an account on signup, we hold the private keys encrypted with the user's
password so we can't access the key itself, keeps track of everything with
100% consistency.

1s block mining and raft consensus settings so pretty much instant and low
resource utilization...and massively scalable.

Sorry to say but if I am in any type of fintech, I would never ever outsource
keeping track of my customer's account balances and source of truth.

~~~
omarish
If you're using a private blockchain where only your systems have access, why
not use postgres with restricted user permissions?

~~~
jonahbenton
Am not the parent but, for example, the Bitcoin blockchain is essentially a
double-entry transaction ledger. Every transaction has to balance inputs and
outputs.

If the product poster is using has that property, then perhaps is a reasonable
choice.

Postgres does not have any ledger balancing primitives.

~~~
andriosr
For Decimals I’m using a hash-chain. So, entries are always balanced, atomic
and immutable. Not a blockchain, as there is no need for consensus, but the
properties for checking integrity are all in there.

------
rgbrgb
This is pretty cool, I'd wonder how it compares to an open source accounting
library like double_entry. I guess I'd be hesitant to integrate with an
external service if I could accomplish the same thing with a library.

Have no idea if there's a market for this (I'm certainly not a customer), but
something none of these libraries are set up to do is convert these balances
to erc-20 tokens. The combo of a SaaS with a simple API like this and a
trusted mint to sync balances to erc-20 tokens could be interesting.

[0]:
[https://github.com/envato/double_entry](https://github.com/envato/double_entry)

~~~
theturtletalks
I would check out [https://frappebooks.com/](https://frappebooks.com/). They
are building an open-source accounting system like Freshbooks. It can also be
used for personal accounting like Mint.

~~~
andriosr
Interesting, thanks!! I know Frappe, it's from the creators of ERPNext. They
are more like a full-suite accounting tool, like Mint, as you mentioned.
Decimals.app is a general-purpose API, it can be used for accounting and other
use cases if you need to build them and can't use Mint and others.

------
seancoleman
I can’t count how many times I’ve individually solved this problem for various
companies, and fixed broken ledger systems. I’m currently dealing with the
terrible legacy decisions of single-precision float database columns leading
to floating-point precision loss on a multi-million $$ eCommerce platform.

What a schlep.

I’m curious, do you store currency values as decimal dollars or integral
cents?

~~~
andriosr
Yep, as @zomglings and @vangale noted, always an integer. Thanks, guys.

They can represent anything you want, cents, mils, and so on.

~~~
pbreit
Ironic that the app name is "Decimals".

Personally, never liked the apps that used integers for what in the real/human
world are decimals. I understand (sort of) why they are used from a tech
perspective. But ultimately, tech is used by humans.

~~~
WrtCdEvrydy
It's an issue with floating point accuracy usually...

2 point decimals can usually be accurate but given enough operations, you can
sometimes get a weird floating error and rounding / clamping is discouraged in
banking.

~~~
ajnin
He's talking about fixed point, not floating point. The decimal type in SQL is
an exact, fixed point numeric type. It can avoid loss of precision, like
integer, but without the scale conversion step.

------
bbrinx
When I run the example code I get "Error: Cannot find module 'decimals'". I'm
on latest Chrome macOS

~~~
andriosr
Noted, I'm working on it. Thanks!

------
jFriedensreich
Not to be "that guy", but if your pitch is that you can keep money
transactions consistent, also make the use of semicolons on the landing page
example consistent. ;) Apart from that it looks really nice, but as a naive
person it would be really cool to give examples of issues i would run into, if
i tried building something like this myself...

~~~
andriosr
No worries at all! I'm here to get feedback and thoughts. Thanks so much for
noticing and letting me know, it's now consistent! It makes a ton of sense to
add the common issues section, it should speak to people having the problem as
soon as they see it. I will work on that.

~~~
ncallaway
I would definitely second that. I don’t have a great grasp on why I shouldn’t
do this myself. Somewhere (it doesn’t have to be on the landing page), I’d
like to hear about why I shouldn’t do this myself.

~~~
andriosr
Got it, I will improve on that. The point is: besides being a consistent
store, Decimals connects to multiple sources of data and make it available in
your ledger automatically. Say you have transactions in Stripe, besides
building the system to store the transactions in-house if you need, you also
have to connect to their webhook to pull the data. Then you need to compute
the usage of your saas, you can also do that on Decimals, just use the
currency of your app (MB, GB, events, etc), now you have payments and usage in
a single consistent store, and so on.

------
zomglings
Having gone through the pain of writing code like this in the past, this looks
amazing. How are you planning to charge for decimals?

In your code sample, you use from: 'Alice' but list transactions for some kind
of complicated balance ID. Where did that ID come from?

~~~
zomglings
Also, your RunKit sample is not working since they don't have the decimals
package available (assuming it's published on npm already).

~~~
andriosr
I'll add a note to the post, thanks! Working on that now.

------
forthwall
Looks pretty cool and useful.

Only note is that the runkit environment doesn't seem to be working. "Error:
Cannot find module 'decimals'"

~~~
andriosr
Thanks! noted, I'm working on it.

------
tathougies
Why is something that should be a library over an ORM or other data store now
a service product?

~~~
andriosr
Thanks for the question! My view is that when you are creating a product and
there is something that can get you faster at delivering your core value to
your customers, it makes sense to leverage it.

From past experiences, on a reasonably big company (>100 engineers) that needs
to do these money movements checks, it would save at least 3 engineers from
support/evolution and not counting the development time for a good ledger.

~~~
tathougies
From my experience as running my own SaaSes, I'd rather have a library over an
ORM, or a self-hosted service. Having yet another cost to manage, another API
to monitor, and an unreliable interface (HTTP over internet), just isn't worth
the cost.

~~~
andriosr
That is very interesting to hear. I would love to better understand the kinds
of problems you may have faced with these systems.

On the cost side, the goal is to charge on average 1/10 of what you currently
spend, so cost is actually a feature. I'm working on a self-hosted version for
some customers that are asking for it, but not due to reliability of HTTP over
the internet, I would love to hear more about this. Can we chat?

------
scrollaway
Cool. Couple questions:

1\. How do you handle / plan to handle multi-currency accounts? (normalize to
single currency vs. Selinger's approach
[https://www.mscs.dal.ca/~selinger/accounting/tutorial.html](https://www.mscs.dal.ca/~selinger/accounting/tutorial.html))
2\. What tech did you use to build all this? db/languages etc.

~~~
andriosr
Great questions, thanks!

The API is currency agnostic, so one account can have many balances from
multiple currencies attached to it. However, you can't do transactions cross
currencies at the moment. You can do it on your side, and use the API to store
the result, both normalized and Selinger are doable. I definitely plan to add
this at some point, thanks for the reference, it's great!

On the tech side, the service is written in Go, and the database is DynamoDB,
everything runs on AWS right now. I'm planning to add support for Cassandra
and MongoDB, as some enterprise customers want to run it inside their
datacenters.

------
bhargav
Money and keeping track of it is a big problem. Depending on your problem
though, its not fully always in your control. For example, we integrate with a
discount calculation service that only supports values up to the 100ths. This
means that we have to introduce rounding as an intermediary and then solve the
"off by one cent" problem, after the fact.

In addition to the problem @joshuakelly mentioned, I think one of the
challenges here will be to gain trust. Asking someone else to keep track of
your books is a pretty tall ask. How does it affect a given company's
auditing? What about SOC Compliance etc? I would suggest you try to address
some of these things.

Best!

~~~
andriosr
That's great feedback, thanks! I agree with both points, handling different
precision strategies from multiple parties is a challenge on itself, we don't
solve it yet, but is definitely on the roadmap. On the trust side, it's a
question of time, as the curve of adoption for any technology, we have been
working with the early adopters now, and providing them the competitive
advantage they deserve for being innovators. Thanks for the comment!

------
RileyJames
SubLedger was another startup in this space a few years ago, which I thought
had the right idea. But they didnt really follow through. They seemed to focus
on uber and their ilk as customers, where as I felt they would have been a
killer if they focused on being the accounting backbone between business apps.
Like Xero is, but api first / only.

[https://www.crunchbase.com/organization/subledger](https://www.crunchbase.com/organization/subledger)

~~~
andy_ppp
Yes, in the end there are only lists of transactions and so great potential
for interacting with them from a central, simple API. It may or may not be
worth having a look at the open banking APIs that are in use here in the UK.

~~~
andriosr
Thanks! I read a couple of specs, didn’t like the design, I think it’s too
complex. But it may be due to the complexities of the UK banking system. From
an integration point of view, it’s definitely something I’m looking at.

------
ianhawes
I thought this sounded familiar. I got an email out of the blue 10 days ago
about this app from the creator:

> Hi!

I run a startup trying to make it easier to create systems that store
transactions and balances.

I found your contact searching the stargazers of the php Money lib:
[https://github.com/moneyphp/money](https://github.com/moneyphp/money)

Are you using it?

The project is in the early stages, I have nothing to sell. I need help to
make sure I will build something useful.

\-- Rob.

~~~
andriosr
Hello Ian, yes! That was me. I reached out to a couple people using money
libraries to better understand how are people dealing with the problem right
now. The goal was to help in the design of the api for client libraries and
get a better sense of how the product fits into different orgs. Thanks for
commenting!

------
justsomeuser
How would this be better than designing a simple SQL schema, and then
generating the ledger as a report?

~~~
jonahbenton
The real answer is that double entry is a different problem, and
SQL/relational databases are not ergonomic for solving it.

Most SQL ledgers are just a table of transactions. What happens when you have
an error/typo in a transaction? SQL databases will ensure that your error gets
safely committed to disk, with zero built in machinery to detect what double
entry knows to be an error in the data.

(I don't know if OP actually solves that problem in their service, but this is
the key idea in double entry.)

Cheers.

~~~
andriosr
Completely agree! I've seen SQL implementations of ledgers fail quite a few
times.

I'm using DynamoDB, but any no-SQL database will do the work (currently
working on Cassandra and MongoDB connectors to enable self-hosting for
enterprise customers)

On the implementation side, it's a mix of both: I'm using the conditional
insert/optimistic locking of no-SQL and modeled the ledger to be a hash-chain
at the application layer. The design is actually simple, and it scales
indefinitely.

Besides that, I'm using DynamoDB streams to build roll-ups of the transactions
and make sure that all transactions are always balancing to zero in real-time.

~~~
jonahbenton
Cool, got it.

Are you actually seeing demand for on-prem hosting? Serious demand such that
you would lose the sale from a customer you cannot live without? Completely
different support model and neither Cassandra and especially Mongo are
anywhere near Dynamo.

I also have seen plenty of cases where balance to zero only at end of day is
feasible, but real time is a good way of picking the right customers. My
completely unsolicited advice- do the same with the DB, stay away from
customers who say they need prem. But I'm just a schmo on the internet. Very
best of luck to you!

~~~
andriosr
A couple of companies asked for it, but I couldn't agree more with you.

We are in the design phase of these implementations, as there is a lot more
than code to consider for a self-hosted version.

Thanks for the advice, it's great to get your view on it.

~~~
ethn
DynamoDB is the wrong technology for this. You can't prevent phantom reads.
Transactional databases (precisely invented for this!) are the way to go. To
quote DDIA:

'A service that allows users to spend money or points needs to check that a
user doesn’t spend more than they have. You might implement this by inserting
a ten‐ tative spending item into a user’s account, listing all the items in
the account, and checking that the sum is positive [44]. With write skew, it
could happen that two spending items are inserted concurrently that together
cause the balance to go negative, but that neither transaction notices the
other.'

~~~
andriosr
Thanks for the comment! It’s a common misunderstanding that no-sql dbs can’t
be used for this, but any would work. Dynamo dB have consistent reads and
conditional inserts, which is sufficient to build an optimistic locking system
that ensures no double spent money.

~~~
ethn
No problem. You should look into this more. Conditional expressions in DDB do
not provide aggregate expressions and can only determinate on single
attributes belonging to the same table.

Consistent reads aren’t enough.

You would need to prevent phantom reads. DDB doesn’t support range locking
since it’s a LSMT. You can contact the AWS solutions engineers or perform a
quick online search: ‘However, neither DynamoDB nor the library support
locking for range queries, thus phantom reads can potentially result in
phantom reads.’

[https://dbdb.io/db/dynamodb](https://dbdb.io/db/dynamodb)

------
Gepsens
I'm actually building a crypto trading system from scratch (like gekko but
more sophisticated). For now not as a SaaS, but even with a simple system, all
the transactional problems occur quite fast. This is really interesting !

~~~
andriosr
That's great! One of the companies using Decimals is building a crypto
exchange, it's been great to see how the API can be extended. They are
creating a multi-signature wallet on top of Decimals, adding a signature to
each transaction. Let's talk, I think it can really accelerate what you are
building.

~~~
Gepsens
I mean, I'm on the client side, so I don't need a ledger to manage wallets,
for now. But as the system evolves, I'll definitely need to 'allocate' budgets
in the form of ledgers, where an algorithm decides to move funds from one
account to another.

------
collinglass
Hi,

I've signed up for early access and tried replying to your emails but I am
unable to reply to your decimals app email address, I get mail failut. Please
reach out with another email, could really use this.

collin at waystocap

------
venantius
We are planning on offering a competitive service to this later on this year.
The major difference for us is that we’re an actual bank, so we need to run
this infra whether you pay for it or not.

~~~
andriosr
Interesting! That's great to hear, I think there is a big market for this. A
lot of companies are struggling to build this in-house, without the required
finance/accounting domain knowledge. I would love to chat, can I reach you on
keybase?

------
Ap0c
Why would you not use an accounting package like Xero to manage this?

~~~
andriosr
Xero is an accounting app, and it has a ton of features. This is a simple API
to validate money movements, it can be used as one of the pieces to build a
dedicated accounting, billing, and other systems if existing solutions like
Xero doesn't work for you. It's general-purpose, where Xero is more a
dedicated app for accounting.

~~~
howmayiannoyyou
Xero user here. Would leave in a second if I could. Why:

\- Next to nothing in terms of expense graphs.

\- Terrible API for polling for alerts based on reports.

\- Saving custom reports not really a thing.

\- Mobile app is hot garbage.

\- Bank feeds drop a lot.

\- My accounting firm not a fan.

\- One light blue skin forever, like being relegated to a blue hell.

\- Integrates with things like Zapier & Integromat, but not deeply.

\- Parsing JSON reporting via Integromat is pure pain.

~~~
andriosr
This is interesting! I heard a lot of complaints about the Xero API, it has
low rate-limits and you need some workarounds to push data in at a fast enough
pace. Definitely not the system to be used at scale.

One thing that is in the roadmap is to bring data from Xero so that you can
interact with it in Decimals. It should give you a much better API, and we
make sure it's going to get synced in the background. Let me know if this is
something you might be interested in getting early access.

------
arthurcolle
This is a great idea, and I think you should pursue it.

Immutability of transactions is obviously a fundamental necessity and coupling
this with GraphQL seems like a great fit.

~~~
andriosr
Thanks! Yes, it is, I will make it more clear on the copy.

------
bluewalt
How did you build the landing page? (any tool?) I like the sleek style, it
reminds me Stripe pages.

~~~
andriosr
Hey! I used one of the [https://cruip.com/](https://cruip.com/) templates, and
the sample code component is from
[https://runkit.com/home](https://runkit.com/home)

~~~
bluewalt
Thanks a lot! Good resources!

------
nnn1234
didnt ledger cli try this with dot ledger that was used by hackclub?

~~~
andriosr
Nice question! Dotledger is a full suit accounting tool To replace Xero
personal finance. Decimals is a primitive API that can be used to build that
or other kinds of applications, but it would be only one of the pieces of the
overall system at the moment.

