🏛 A scriptable financial ledger, designed to make it easy to model complex financial transactions

Related tags

Financial ledger
Overview

Numary Ledger test

Numary is a programmable financial ledger that wants to make building financial apps safe, fun and cheap.

Building financial software is both critical and notably hard. The same bugs are repeated again and again, paving the highway to catastrophes.

Numary wants to tackle this issue with a ledger that provides atomic multi-postings transactions and is programmable in Numscript, a built-in language dedicated to money movements. It will shine for apps that require a lot of custom, money-touching code such as:

  • E-commerce with complex payments flows, payments splitting, such as marketplaces
  • Company-issued currencies systems, e.g. Twitch Bits
  • In-game currencies, inventories and trading systems, e.g. Fortnite V-Bucks
  • Payment gateways using non-standard assets, e.g. learning credits
  • Local currencies and complementary finance

Getting started

Numary works as a standalone binary, the latest of which can be downloaded from the releases page. You can move the binary to any executable path, such as to /usr/local/bin.

example.num numary exec quickstart example.num # Get the balances of drivers:042 curl -X GET http://localhost:3068/quickstart/accounts/drivers:042 # List transactions curl -X GET http://localhost:3068/quickstart/transactions ">
numary server start

# Submit a first transaction
echo "
send [USD/2 599] (
  source = @world
  destination = @payments:001
)

send [USD/2 599] (
  source = @payments:001
  destination = @rides:0234
)

send [USD/2 599] (
  source = @rides:0234
  destination = {
    85/100 to @drivers:042
    15/100 to @platform:fees
  }
)
" > example.num

numary exec quickstart example.num

# Get the balances of drivers:042
curl -X GET http://localhost:3068/quickstart/accounts/drivers:042

# List transactions
curl -X GET http://localhost:3068/quickstart/transactions

Documentation

You can find the complete Numary documentation at docs.numary.com

Dashboard

control-screenshot

A simple dashboard is built in the ledger binary, to make it easier to visualize transactions. It can be started with:

numary ui

Alpha & Roadmap

Please note that is currently in Alpha for a few weeks. The goal of the Alpha is to start taking early feedback from the community.

During the Alpha,

  • Breaking changes can happen between releases
  • Critical bugs can be discovered
  • Documentation will be incomplete

Beyond Alpha, the roadmap is:

  • Alpha: Feedback & Refining
  • Beta: Stabilizing
  • RC: API Freeze
  • 1.0.0: 🎉
Comments
  • feat(client): add generator config to generate Ledger java client

    feat(client): add generator config to generate Ledger java client

    Add generator config to generate Ledger java client

    I’ve tried to mimic what you did for the SDKs for other languages. There’s a few open things though which are probably best for Formance to pick up.

    • [ ] Formance needs to define release process (.github/workflows/release.yml.mustache) + create repo
    • [ ] Formance needs to define licenseName/licenseUrl (in additionalProperties)
    • [ ] Please define servers url in swagger.json so that when generating not the hardcoded “localhost” is used. This needs to be fixed before the SDK can really be used by others. Please see https://stackoverflow.com/a/72182063/1422070 for a good approach I believe
    • [ ] For some reason, a few classes are named like GetAccount200Response by default. I use inlineSchemaNameMappings setting to manually override this to a normal name (like GetAccountResponse). There are also classes for error status codes like GetAccount400Response, but although these are generated they are not used by other classes, so I don’t bother with renaming those at this time. But perhaps we can skip generation somehow?
    • [ ] Tests are generated but they don’t actually do anything. I can define some manual tests, just not sure what your strategy is here. Just define them manually and include them in the final repo? It seems that’s what you do for the Python SDK

    Type of change

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [X] New feature (non-breaking change which adds functionality)
    • [ ] Refactoring / Technical debt

    What parts of the code are impacted ?

    No direct impact, since the github workflows still need to be modified to call the generation task for Java.

    Checklist:

    • [X] My code follows the style guidelines of this project
    • [X] I have performed a self-review of my code
    • [ ] I have commented my code, particularly in hard-to-understand areas
    • [ ] I have made corresponding changes to the documentation
    • [ ] My changes generate no new warnings
    • [ ] I have added tests that prove my fix is effective or that my feature works
    • [X] New and existing unit tests pass locally with my changes
    @domain/sdk 
    opened by edwardmp 9
  • Numary UI not displaying any Data

    Numary UI not displaying any Data

    Hi there,

    i tried displaying the UI right now and it comes up with this: image

    there is data in the quickstart ledger: {"cursor":{"page_size":15,"has_more":false,"total":3,"remaning_results":0,"data":[{"address":"world","contract":"default"},{"address":"users:001","contract":"default"},{"address":"central_bank","contract":"default"}]},"ok":true}

    opened by thephilluk 8
  • NUM-384 filters account by their balance

    NUM-384 filters account by their balance

    This feature allows us to filters the accounts we get using the /{ledger}/accounts route by their balance

    The request now takes two more optionnal parameters, and <balance_operator>

    • balance : int64 that represents the balance volume of the account
    • balance_operator : comparison operator, can be gt, gte, e, lt, lte

    I also tried to make the tests easier to read by bracketing them

    opened by jdupas22 5
  • Numary UI

    Numary UI

    HI there,

    I tried opening the Dashboard via the SSH link i have, but it just came up with the following error: 2021/07/22 12:57:08 exec: "xdg-open": executable file not found in $PATH I have already changed the HTML bind address to the external IP. Is there some URL I can visit to open the Dashboard or does it have to be started manually?

    thanks, Philip

    opened by thephilluk 5
  • chore: remove duplicate go mod vendor

    chore: remove duplicate go mod vendor

    Title

    Test already depends on vendor task, which already runs go mod vendor

    Type of change

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [ ] New feature (non-breaking change which adds functionality)
    • [X] Refactoring / Technical debt

    What parts of the code are impacted ?

    Taskfile for Go SDK

    Checklist:

    • [X] My code follows the style guidelines of this project
    • [X] I have performed a self-review of my code
    • [X] I have commented my code, particularly in hard-to-understand areas
    • [X] I have made corresponding changes to the documentation
    • [X] My changes generate no new warnings
    • [X] I have added tests that prove my fix is effective or that my feature works
    • [X] New and existing unit tests pass locally with my changes
    good first issue 
    opened by edwardmp 4
  • feat: Add production server on openapi spec.

    feat: Add production server on openapi spec.

    Add servers on OpenAPI spec

    This add "servers" property on OpenAPI specification.

    Type of change

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [X] New feature (non-breaking change which adds functionality)
    • [ ] Refactoring / Technical debt

    What parts of the code are impacted ?

    OpenAPI spec.

    Checklist:

    • [ ] My code follows the style guidelines of this project
    • [ ] I have performed a self-review of my code
    • [ ] I have commented my code, particularly in hard-to-understand areas
    • [ ] I have made corresponding changes to the documentation
    • [ ] My changes generate no new warnings
    • [ ] I have added tests that prove my fix is effective or that my feature works
    • [ ] New and existing unit tests pass locally with my changes
    opened by gfyrag 3
  • feat: Add configurable pageSize on paginated requests

    feat: Add configurable pageSize on paginated requests

    Add configurable limit on paginated request

    This add the query parameter 'page_size' on both GET /transactions, GET /accounts and GET /balances endpoints. The parameter is capped to a value of 1000. The default value still the same as before (15).

    The PR also fix some tests around pagination which was working but was not doing the right thing (see api/controllers/pagination_test.go line 209).

    Type of change

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [X] New feature (non-breaking change which adds functionality)
    • [ ] Refactoring / Technical debt

    What parts of the code are impacted ?

    • pkg/api/controllers
    • pkg/storage

    Checklist:

    • [X] My code follows the style guidelines of this project
    • [X] I have performed a self-review of my code
    • [X] I have commented my code, particularly in hard-to-understand areas
    • [X] I have made corresponding changes to the documentation
    • [X] My changes generate no new warnings
    • [X] I have added tests that prove my fix is effective or that my feature works
    • [X] New and existing unit tests pass locally with my changes
    opened by gfyrag 3
  • implement transaction reversion

    implement transaction reversion

    Signed-off-by: Henry Jackson [email protected]

    Closes #52

    ▶ curl -X POST -H "Content-Type: application/json" http://localhost:3068/test-01/transactions -d \                                                           
    '{
       "postings": [
         {
           "source": "world",
           "destination": "test:001",
           "amount": 100,
           "asset": "USD/2"
         }
       ],
       "reference": "foobar"
     }'
    
    {"ok":true}%                                                                                                                                                  
    
    ▶ curl -X GET http://localhost:3068/test-01/transactions | jq .                                                                                              
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   352  100   352    0     0   171k      0 --:--:-- --:--:-- --:--:--  171k
    {
      "cursor": {
        "page_size": 15,
        "has_more": false,
        "total": 1,
        "remaining_results": 0,
        "data": [
          {
            "txid": 0,
            "postings": [
              {
                "source": "world",
                "destination": "test:001",
                "amount": 100,
                "asset": "USD/2"
              }
            ],
            "reference": "foobar",
            "timestamp": "2021-10-21T23:39:28-04:00",
            "hash": "c516d65aa60b8272a6b1caac6355e3b899b72a070c0c01f64ebb581ba119b904",
            "metadata": {}
          }
        ]
      },
      "err": null,
      "ok": true
    }
    
    ▶ curl -X POST http://localhost:3068/test-01/transactions/0/revert | jq .                                                                                    
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    11  100    11    0     0   3666      0 --:--:-- --:--:-- --:--:--  3666
    {
      "ok": true
    }
    
    ▶ curl -X GET http://localhost:3068/test-01/transactions | jq .                                                                                              
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   661  100   661    0     0   322k      0 --:--:-- --:--:-- --:--:--  322k
    {
      "cursor": {
        "page_size": 15,
        "has_more": false,
        "total": 2,
        "remaining_results": 0,
        "data": [
          {
            "txid": 1,
            "postings": [
              {
                "source": "test:001",
                "destination": "world",
                "amount": 100,
                "asset": "USD/2"
              }
            ],
            "reference": "revert_foobar",
            "timestamp": "2021-10-21T23:39:54-04:00",
            "hash": "bc946b08061fc4c8076b009281f8a5104417498834bd94c61ddc6477334d949e",
            "metadata": {}
          },
          {
            "txid": 0,
            "postings": [
              {
                "source": "world",
                "destination": "test:001",
                "amount": 100,
                "asset": "USD/2"
              }
            ],
            "reference": "foobar",
            "timestamp": "2021-10-21T23:39:28-04:00",
            "hash": "c516d65aa60b8272a6b1caac6355e3b899b72a070c0c01f64ebb581ba119b904",
            "metadata": {
              "scheme/state": "reverted",
              "scheme/state/reverted-by": "1"
            }
          }
        ]
      },
      "err": null,
      "ok": true
    }
    
    @domain/core @domain/api @domain/ledger @domain/storage 
    opened by henry-jackson 3
  • Revert transaction

    Revert transaction

    Summary

    We should be able to revert a transaction without having to build the reverse transaction

    Proposal

    POST /:ledger/transactions/:txid/revert
    

    Expected behaviors

    Given the transaction:

    {
      "txid": 0,
      "postings": [
        {
          "source": "world",
          "destination": "users:001",
          "amount": 100,
          "asset": "COIN"
        },
        {
          "source": "users:001",
          "destination": "payments:001",
          "amount": 100,
          "asset": "COIN"
        }
      ]
    }
    

    The revert endpoint should attempt to commit the exact reverse transaction:

    {
      "txid": 1,
      "postings": [
        {
          "source": "payments:001",
          "destination": "users:001",
          "amount": 100,
          "asset": "COIN"
        },
        {
          "source": "users:001",
          "destination": "world",
          "amount": 100,
          "asset": "COIN"
        }
      ]
    }
    
    enhancement contrib/tier-3 
    opened by altitude 3
  • Adding a description/custom id to transactions?

    Adding a description/custom id to transactions?

    I think numary is the right fit for a project I'm planning on, and I'm wondering if adding descriptions (and perhaps filtering by them in GET /{ledger}/transactions see #30 ) would be a planned feature? In my case, it would be useful to correlate the initial set of transactions from a public blockchain to the internal numary ledger.

    For both this and #30, I could try a PR when I get to coding the accounting part of my project. (that is, if you consider these features would be useful as part of numary)

    enhancement 
    opened by karmanyaahm 3
  • feat: Idempotent requests

    feat: Idempotent requests

    Add idempotent requests

    This add idempotent requests. The feature is applied on endpoints which write to the database :

    • Create transaction (also batch and numscript)
    • Update metadata (account or transaction)
    • Revert transaction

    This work by passing a header named "Idempotency-Key".

    When requesting the service with a IK, if the IK has already been used on another request terminated with success (Status code 2XX), the same response will be returned, plus a header named "Idempotency-Hit" with the value "true". Given a IK, if the request does not match the originated request, either if the path or the body does not match, the service will responds with a 400 status code.

    Warning : The scope of the idempotency keys are bound to a specific ledger. Therefore a same IK can be used on two differents ledgers without trigger any alert.

    opened by gfyrag 2
  • Negative values for account balance

    Negative values for account balance

    Is your feature request related to a problem? Please describe. About the fact that accounts can't have negative values, is it possible to overcome this in some way ? (In the formance documentation: Accounts in Formance Ledger cannot go negative! (Except for the special @world account).)

    enhancement 
    opened by agallan 0
  • Support for back dated transactions

    Support for back dated transactions

    Is your feature request related to a problem? Please describe. In some scenarios it is needed to create transactions that happened in the past and not in the moment they were committed.

    Summary

    Solution proposal Make the api accept a backdate property

    {
      "postings": [
        {
          "source": "alice",
          "destination": "teller",
          "amount": 100,
          "asset": "COIN"
        },
        {
          "source": "teller",
          "destination": "alice",
          "amount": 5,
          "asset": "GEM"
        }
      ],
      backdate: $timestamp
    }
    

    This should update the balances accordingly or throw an error if subsequent transactions cannot be applied to avoid leaving the system in an invalid state

    enhancement 
    opened by nicoabie 5
  • Adding numary to nixos package directory

    Adding numary to nixos package directory

    I'm trying to learn and use Nix, so to test that and numary at the same time I've proposed adding numary to the Nixos package directory.

    https://github.com/NixOS/nixpkgs/pull/191106

    I've followed the instructions for building present at the current Dockerfile but I could use some help with the tests.

    opened by pcasaretto 1
  • feat: use sharedanalytics package

    feat: use sharedanalytics package

    feat: use sharedanalytics package

    This basically extract the analytics code to go-libs library (https://github.com/numary/go-libs/pull/9). Please review go-libs before.

    Type of change

    • [ ] Bug fix (non-breaking change which fixes an issue)
    • [X] New feature (non-breaking change which adds functionality)
    • [ ] Refactoring / Technical debt
    @domain/cmd 
    opened by gfyrag 3
  • refactor: volumes aggregation

    refactor: volumes aggregation

    Remove post commit volumes and pre commit volumes calculation from transaction batches. Aggregation is provided by the core using functions AggregatePostCommitVolumes() and AggregatePreCommitVolumes(). This simplify a bit the transaction processing and remove duplicate codes.

    opened by gfyrag 1
  • initializing ledger store: open migrates\\0-init-schema: file does not exist

    initializing ledger store: open migrates\\0-init-schema: file does not exist

    After i Download and Install the the pre-compiled binary "numary_x.y.z_Windows-64bit.zip",

    I fellow the tutos :

    numary config init

    numary storage init

    numary version

    Version: 1.7.1 Date: 2022-08-02T10:37:19Z Commit: 22b2d2c

    numary server start --debug

    ok

    but when, i start testing

    intro.num : send [COIN 100] ( source = @world destination = @centralbank )

    numary exec dunshire intro.num

    i get : time="2022-08-10T16:07:33+01:00" level=fatal msg=EOF

    in the client side :

    numary exec quickstart example.num time="2022-08-10T05:44:44+01:00" level=fatal msg=EOF

    and this error in the server side:

    time="2022-08-10T16:18:02+01:00" level=debug msg="QueryRowContext: SELECT ledger FROM ledgers WHERE ledger = ? [dunshire]" time="2022-08-10T16:18:02+01:00" level=debug msg="ExecContext: INSERT INTO ledgers (ledger, addedAt) VALUES (?, ?) ON CONFLICT DO NOTHING [dunshire 2022-08-10 16:18:02.8947982 +0100 CET m=+7.719215001]" time="2022-08-10T16:18:02+01:00" level=debug msg="Initialize store" time="2022-08-10T16:18:02+01:00" level=info msg=Request ip=127.0.0.1 latency=2.3679ms method=POST path=/dunshire/script status=500 user_agent=Go-http-client/1.1 time="2022-08-10T16:18:02+01:00" level=error msg="initializing ledger store: open migrates\0-init-schema: file does not exist"

    ps: I use sqlite as Driver ... server: http: basic_auth: "" bind_address: localhost:3068 storage: cache: true dir: c:/.numary/data driver: sqlite postgres: conn_string: postgresql://localhost/postgres sqlite: db_name: numary ui: http: bind_address: localhost:3068 version: 1.7.1

    bug 
    opened by ZinZingoo 1
Releases(v1.8.0-rc.2)
Owner
Numary
Making money programmable
Numary
Go library containing a collection of financial functions for time value of money (annuities), cash flow, interest rate conversions, bonds and depreciation calculations.

go-finance Go library containing a collection of financial functions for time value of money (annuities), cash flow, interest rate conversions, bonds

Alejandro Pedraza 143 Sep 26, 2022
A go port of numpy-financial functions and more.

go-financial This package is a go native port of the numpy-financial package with some additional helper functions. The functions in this package are

Razorpay 269 Sep 17, 2022
Embedded database for accounts transactions.

transaction Embedded transactional database of accounts, running in multithreaded mode. Coverage 92.8% The library operates only with integers. If you

Eduard 114 Aug 20, 2022
Converts grouped transactions in a ZKB transaction CSV (incl. details) to single transactions

ZKB Converter Converts grouped transactions in a ZKB transaction CSV (incl. deta

Tobias Nehrlich 0 Dec 26, 2021
CRUDist Model Driven Web Development. Automagically generate CRUD APIs from your model.

CRUDist - Model Driven API Development Automagicaly create CRUD APIs for your gorm models. Example Model definition type BaseModel struct { ID

null 1 Nov 15, 2021
Transmo - Transform Model into another model based on struct for Go (Golang).

Transmo Transmo is a Go library for transform model into another model base on struct. This library detect your field name to copy that into another m

Reza Ramadhan Irianto 0 Jan 7, 2022
A distributed, proof of stake blockchain designed for the financial services industry.

Provenance Blockchain Provenance is a distributed, proof of stake blockchain designed for the financial services industry.

Provenance Blockchain, Inc. 60 Sep 30, 2022
An easy-to-use platform for creating microservices without complex infrastructure solutions.

RPCPlatform An easy-to-use platform for creating microservices without complex infrastructure solutions. Only etcd required. Out of the box you get a

Oleg Trifonov 0 Jan 4, 2022
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

mattn 1.3k Sep 25, 2022
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

mattn 1.3k Sep 20, 2022
Instant messaging platform. Backend in Go. Clients: Swift iOS, Java Android, JS webapp, scriptable command line; chatbots

Tinode Instant Messaging Server Instant messaging server. Backend in pure Go (license GPL 3.0), client-side binding in Java, Javascript, and Swift, as

Tinode 9.2k Oct 1, 2022
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

mattn 1.3k Sep 25, 2022
BackEndForEverything a scriptable reverse proxy

BEFE the BackEnd For Everything BEFE is a scriptable reverse proxy. It simplifies checking, rewriting and transforming incoming request through the he

MBIct 2 Nov 8, 2021
Simple and easy to use client for stock market, forex and crypto data from finnhub.io written in Go. Access real-time financial market data from 60+ stock exchanges, 10 forex brokers, and 15+ crypto exchanges

go-finnhub Simple and easy to use client for stock, forex and crpyto data from finnhub.io written in Go. Access real-time market data from 60+ stock e

Miles Croxford 76 Sep 26, 2022
An open-source, distributed, cloud-native CD (Continuous Delivery) product designed for developersAn open-source, distributed, cloud-native CD (Continuous Delivery) product designed for developers

Developer-oriented Continuous Delivery Product ⁣ English | 简体中文 Table of Contents Zadig Table of Contents What is Zadig Quick start How to use? How to

null 0 Oct 19, 2021
A terminal designed for anyone to use and designed for any platform

A terminal designed for anyone to use and designed for any platform. Which includes the basic features of any terminal and includes friendly commands to perform tools such as ping, traceroute, generate key pairs, encrypt/decrypt, router security actions, etc. All of the source code is done in Go.

Karun Kanda 1 Jan 25, 2022
An easy tool to apply transactions to the current EVM state. Optimized for MEV.

sibyl A more embedded version of fxfactorial/run-evm-code. This tool makes it easy to apply transactions to the current EVM state. Call it a transacti

Dialectic 63 Sep 20, 2022
Null Types, Safe primitive type conversion and fetching value from complex structures.

Typ Typ is a library providing a powerful interface to impressive user experience with conversion and fetching data from built-in types in Golang Feat

Gurukami 32 Aug 5, 2022
godesim Simulate complex systems with a simple API.

godesim Simulate complex systems with a simple API. Wrangle non-linear differential equations while writing maintainable, simple code. Why Godesim?

Patricio Whittingslow 20 Sep 27, 2022