ledger

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package ledger generates a deterministic UK payments ledger shaped like a git object graph.

The three layers map onto git's three object types, which is what lets one visualiser drill through either without special cases:

  • a transaction is the commit: the money movement itself, from payer to payee, chained to the transaction before it and occasionally to two, where a settlement nets several payments together.
  • a log is the tree: the history of the transaction's state transitions. One log per status the payment reached as it moved through its scheme, gathered under a history log for the transaction as a whole.
  • an entry is the blob: the double entry posted at one of those transitions, balanced across its debit and credit legs.

Postings therefore hang off the transition that caused them rather than off the transaction. Authorisation recognises the liability or the debt, clearing or settlement moves the money at the bank, and a return reverses that movement. Transitions where nothing is posted, such as submission to the scheme, carry no entry at all.

Everything is content-addressed, so entries deduplicate exactly as blobs do in git. A recurring charge posting the same legs at the same amounts resolves to one entry node shared by every transaction that posted it, which is what turns the ledger from a tree into a DAG and gives a containment layout something real to handle.

Amounts are held in pence and posted gross, with VAT at the standard rate split out to its own nominal account so every entry balances.

This package is example code. It is here to demonstrate the github.com/danielriddell21/merkelbrot/graph.Source interface and carries no compatibility promise.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Seed makes generation reproducible. Default 1.
	Seed uint64
	// Transactions is how many transactions to post. Default 12.
	Transactions int
	// Settlements is how many of those net several earlier payments together,
	// giving the chain merge points. Default is one per eight transactions.
	Settlements int
}

Config describes the ledger to generate. The zero value is usable.

type Source

type Source struct {
	// contains filtered or unexported fields
}

Source is a generated payments ledger.

func New

func New(cfg Config) *Source

New generates a ledger from the configuration.

Example

ExampleNew walks one transaction the way the visualiser zooms into it: the transaction, its state transition history, and the double entry posted at each transition that moved money.

package main

import (
	"fmt"
	"slices"

	"github.com/danielriddell21/merkelbrot/examples/ledger"
	"github.com/danielriddell21/merkelbrot/graph"
)

func main() {
	g, err := graph.New(ledger.New(ledger.Config{Seed: 4, Transactions: 6}))
	if err != nil {
		panic(err)
	}

	head := slices.Collect(g.Roots())[0]
	txn, _ := g.Node(head)
	fmt.Println("transaction:", txn.Label)

	for child := range g.Children(head) {
		history, _ := g.Node(child)
		if history.Kind != "log" {
			continue
		}
		for step := range g.Children(child) {
			status, _ := g.Node(step)
			fmt.Printf("  %s\n", status.Label)
			for posted := range g.Children(step) {
				entry, _ := g.Node(posted)
				for _, f := range entry.Payload {
					if f.Key == "narrative" {
						fmt.Printf("    %s\n", f.Value)
					}
				}
			}
		}
	}
}
Output:
transaction: £1,250.00 Camden Print Co
  Initiated
  Mandate Checked
  Submitted
  Authorised
    Purchase recognised
  Cleared
    Supplier payment
  Settled

func (*Source) Len

func (s *Source) Len() int

Len reports how many distinct nodes were generated.

func (*Source) Node

func (s *Source) Node(id string) (graph.Node[string], bool)

Node returns the node with the given ID.

func (*Source) Roots

func (s *Source) Roots() iter.Seq[string]

Roots yields the most recent transaction, which reaches the whole chain.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL