Ledgering API server for financial systems.
2.6K
NetLedger is a thread-safe ledgering library for .NET 8.0 and .NET 10.0 that provides tenant-aware debit/credit workflows with auditable pending and committed entry lifecycles. It supports SQLite for embedded deployments and MySQL, PostgreSQL, and SQL Server for external database deployments.





NetLedger v3.0.0 is the tenant-aware release. Public objects now use PrettyId string IDs such as acct_..., ent_..., ten_..., usr_..., and cred_...; accounts and entries carry TenantId; and account/entry metadata can be set with Labels and Tags.
What is new in v3.0.0:
/v1/tenants/{tenantId}/... route aliases and x-tenant-id support preserve existing /v1 paths while making tenant scope explicit.acct_, ent_, ten_, usr_, and cred_.List<string> Labels and Dictionary<string,string> Tags are available in library models, REST payloads, SDKs, Postman, and dashboard forms.GET /openapi.json, the dashboard API Explorer executes requests with the signed-in session, REST_API.md and Postman cover tenant and metadata filters, and the .NET, JavaScript/TypeScript, and Python SDKs expose v3 search/enumeration options.Test.Shared, Test.Automated, Test.Xunit, and Test.Nunit for provider certification and behavior coverage.Authentication flow:
POST /v1/auth/tenants with { "Email": "[email protected]" }.POST /v1/auth/login with tenant ID, email, and password.Session.Token as Authorization: Bearer <token> and send x-tenant-id for tenant-scoped requests.Credential management is available through /v1/credentials and tenant-scoped credential routes. The legacy /v1/apikeys management paths are removed in v3.
Minimal v3 library example:
using NetLedger;
await using Ledger ledger = new Ledger("accounting.db");
string accountId = await ledger.CreateAccountAsync("Operating Account", 1000.00m);
await ledger.AddCreditAsync(accountId, 500.00m, "Customer payment");
Balance balance = await ledger.CommitEntriesAsync(accountId);
NetLedger is designed for developers building applications that require:
Ideal use cases: Financial applications, expense tracking systems, point-of-sale systems, accounting software, multi-user financial platforms, billing systems, payment processing, and applications requiring account-level debit/credit ledgers with strong auditability.
Choose the approach that best fits your needs:
Install the library directly into your .NET application:
dotnet add package NetLedger
Or via NuGet Package Manager:
Install-Package NetLedger
Then use it in your code:
using NetLedger;
// Initialize ledger (creates or opens SQLite database)
Ledger ledger = new Ledger("accounting.db");
// Create an account with optional initial balance
string accountId = await ledger.CreateAccountAsync("Operating Account", 1000.00m);
// Add a pending credit
string creditId = await ledger.AddCreditAsync(accountId, 500.00m, "Customer payment");
// Add a pending debit
string debitId = await ledger.AddDebitAsync(accountId, 150.00m, "Supplier invoice");
// Check balances before commit
Balance balance = await ledger.GetBalanceAsync(accountId);
Console.WriteLine($"Committed: ${balance.CommittedBalance}"); // 1000.00
Console.WriteLine($"Pending: ${balance.PendingBalance}"); // 1350.00
// Commit all pending entries
balance = await ledger.CommitEntriesAsync(accountId);
Console.WriteLine($"Committed: ${balance.CommittedBalance}"); // 1350.00
// Cleanup
await ledger.DisposeAsync();
Clone the repository and build locally:
# Clone the repository
git clone https://github.com/jchristn/NetLedger.git
cd NetLedger
# Build the solution
dotnet build src/NetLedger.sln
# Run the interactive test application
dotnet run --project src/Test/Test.csproj
# Run the automated test suite against SQLite
dotnet run --project src/Test.Automated/Test.Automated.csproj -- --type sqlite
# Run the REST API server
dotnet run --project src/NetLedger.Server/NetLedger.Server.csproj
Run NetLedger Server and Dashboard using Docker Compose:
# Navigate to the docker directory
cd docker
# Start the server and dashboard
docker compose up -d
# View logs
docker compose logs -f
This starts:
http://localhost:8080 - REST API serverhttp://localhost:3000 - Web-based management UIFresh deployments create tenant default with admin@netledger / password.
To stop the services:
docker compose down
The Docker setup uses configuration files in the docker/server/ directory:
netledger.json - Server configuration:
{
"Webserver": {
"Hostname": "+",
"Port": 8080,
"Ssl": false
},
"Logging": {
"EnableConsole": true,
"LogRequests": true
},
"Authentication": {
"Enabled": true,
"DefaultAdminKey": "netledgeradmin"
},
"Database": {
"Type": "Postgresql",
"Hostname": "postgres",
"Port": 5432,
"Username": "netledger",
"Password": "netledger",
"DatabaseName": "netledger",
"Schema": "public",
"RequireEncryption": false,
"ConnectionTimeoutSeconds": 30,
"MaxPoolSize": 100,
"LogQueries": false
}
}
NetLedger includes a web-based dashboard for managing accounts and viewing transactions.
With Docker (recommended):
cd docker
docker compose up -d
For development:
cd src/NetLedger.Dashboard
npm install
npm run dev
http://localhost:3000 in your browserhttp://localhost:5173 in your browser (Vite default port)The dashboard provides:
GET /openapi.jsonNetLedger provides official SDKs for integrating with the REST API server:
dotnet add package NetLedger.Sdk
using NetLedger.Sdk;
// Create a client with a session token or credential access key.
using NetLedgerClient client = new NetLedgerClient("http://localhost:8080", "netledgeradmin", "default");
// Create an account
Account account = await client.Account.CreateAsync("My Account");
// Add credits and debits
await client.Entry.AddCreditAsync(account.Id, 100.00m, "Deposit");
await client.Entry.AddDebitAsync(account.Id, 25.50m, "Purchase");
// Get balance and commit
Balance balance = await client.Balance.GetAsync(account.Id);
await client.Balance.CommitAsync(account.Id);
// API Explorer and Request History support
string openApiJson = await client.Service.GetOpenApiJsonAsync();
EnumerationResult<RequestHistoryEntry> history = await client.RequestHistory.EnumerateAsync(new RequestHistoryQuery { MaxResults = 25 });
See sdk/sdk-csharp/NetLedger.Sdk/README.md for full documentation.
npm install netledger-sdk
import { NetLedgerClient } from 'netledger-sdk';
// Create a client with a session token or credential access key.
const client = new NetLedgerClient('http://localhost:8080', 'netledgeradmin', { tenantId: 'default' });
// Create an account
const account = await client.account.create('My Account');
// Add credits and debits
await client.entry.addCredit(account.Id, 100.00, 'Deposit');
await client.entry.addDebit(account.Id, 25.50, 'Purchase');
// Get balance and commit
const balance = await client.balance.get(account.Id);
await client.balance.commit(account.Id);
// API Explorer and Request History support
const openApiSpec = await client.service.getOpenApiSpec();
const history = await client.requestHistory.enumerate({ MaxResults: 25 });
See sdk/sdk-js/README.md for full documentation.
When running NetLedger Server (via Docker or directly), a full REST API is available for programmatic access.
Base URL: http://localhost:8080
Authentication: User sessions and credentials are accepted as bearer tokens via Authorization: Bearer <token-or-access-key>. Credential authentication can also use x-access-key and x-secret-key. Tenant scope can be supplied with x-tenant-id or tenant-scoped routes.
# Health check
curl http://localhost:8080/
# Create an account with label/tag metadata
curl -X PUT http://localhost:8080/v1/accounts \
-H "Authorization: Bearer netledgeradmin" \
-H "x-tenant-id: default" \
-H "Content-Type: application/json" \
-d '{"Name":"My Account","InitialBalance":100.00,"Labels":["operating","blue"],"Tags":{"department":"finance","color":"blue"}}'
# Add a credit with label/tag metadata
curl -X PUT http://localhost:8080/v1/accounts/{accountId}/credits \
-H "Authorization: Bearer netledgeradmin" \
-H "x-tenant-id: default" \
-H "Content-Type: application/json" \
-d '{"Amount":50.00,"Notes":"Customer payment","Labels":["blue"],"Tags":{"color":"blue"}}'
# Search entries by amount bounds, label, tag, and ordering
curl "http://localhost:8080/v1/accounts/{accountId}/entries?debitMin=5&debitMax=50&labels=blue&tags=color=blue&ordering=AmountDescending" \
-H "Authorization: Bearer netledgeradmin" \
-H "x-tenant-id: default"
# Get balance
curl http://localhost:8080/v1/accounts/{accountId}/balance \
-H "Authorization: Bearer netledgeradmin" \
-H "x-tenant-id: default"
# Commit pending entries
curl -X POST http://localhost:8080/v1/accounts/{accountId}/commit \
-H "Authorization: Bearer netledgeradmin" \
-H "x-tenant-id: default" \
-H "Content-Type: application/json" \
-d '{}'
For complete API documentation, see REST_API.md.
MIT License - See LICENSE.md for details
See CHANGELOG.md for complete version history.
Content type
Image
Digest
sha256:e7ddee4f3…
Size
129.1 MB
Last updated
about 1 month ago
docker pull jchristn77/netledger