Ledger SDK

Ruby SDK for the Ledger API, routed through the Fluence API gateway. The SDK is read-only — browsing containers, accounts, positions, inventories, and balances — except for a container's characteristics (update) and its fees/fee-exclusions management (list, create, update, destroy).

Installation

Add the gem and its fluence-gateway-client runtime dependency to your application's Gemfile (both are hosted on GitHub Packages):

source 'https://rubygems.pkg.github.com/fluence-eu' do
  gem 'fluence-gateway-client'
  gem 'ledger-sdk'
end

Then run:

bundle install

Configuration

Credentials and gateway URLs are managed by fluence-gateway-client. Set APPCENTER_CLIENT_ID and APPCENTER_CLIENT_SECRET and you're done — the SDK targets the ledger service on the Fluence gateway out of the box (paths are prefixed with /backend/ledger/).

For overrides (URL, profile, SSL, etc.), see the fluence-gateway-client README.

Usage

Containers

# List all containers
containers = Ledger::Sdk.Container.list

# Get a specific container (includes its accounts)
container = Ledger::Sdk.Container(42).data

Accounts

# List accounts for a container
accounts = Ledger::Sdk.Container(42).accounts.list

# Get a specific account
 = Ledger::Sdk.Container(42).accounts(7).data

Balances

Balances are accessed by name from a container or an account. Known names: official, official_with_updated_price, transparent, transparent_with_updated_price. Names are not validated by the SDK — an unknown name yields an empty list.

# Recent official balances of a container
balances = Ledger::Sdk.Container(42).balances('official').list

# Recent transparent balances of an account
balances = Ledger::Sdk.Container(42).accounts(7).balances('transparent').list

balances.first.data
# => { 'effective_date' => '2026-06-10', 'currency' => 'EUR', 'value' => 1250000.0 }

Fees, fee exclusions and fee kinds

Fees and fee exclusions are attached to a container. Unlike most of the SDK they are writable: they can be listed, created, updated and destroyed.

# List fees for a container
fees = Ledger::Sdk.Container(42).fees.list

# Filter fees by kind and as-of date
fees = Ledger::Sdk.Container(42).fees.list { { filters: { kind: 'financial_management', as_of: '2026-01-01' } } }

# Create a fee
fee = Ledger::Sdk.Container(42).fees.create(kind: 'financial_management', rate: 0.01)

# Update a fee
fee = Ledger::Sdk.Container(42).fees(5)
fee.update(rate: 0.02)

# Destroy a fee (the instance must not be reused afterwards)
fee.destroy

Fee exclusions work the same way, and additionally support a code filter:

# List fee exclusions for a container
exclusions = Ledger::Sdk.Container(42).fee_exclusions.list

# Filter fee exclusions by kind, code and as-of date
exclusions = Ledger::Sdk.Container(42).fee_exclusions.list do
  { filters: { kind: 'financial_management', code: 'FM-1', as_of: '2026-01-01' } }
end

# Create, update and destroy work the same way as fees
exclusion = Ledger::Sdk.Container(42).fee_exclusions.create(kind: 'financial_management')
exclusion.update(code: 'FM-1')
exclusion.destroy

FeeKind is a global, read-only registry of every fee kind the Ledger API understands. It is not nested under a container, has no show endpoint, and the /fee_kinds endpoint ignores query params — list always returns the full registry:

Ledger::Sdk.FeeKind.list

Positions

# List positions of an account
positions = Ledger::Sdk.Container(42).accounts(7).positions.list

positions.first.data
# => { 'id' => 3, 'currency' => 'USD', 'quantity' => 100.0, 'primary_code' => 'US0378331005', ... }

# List every position of a container in one call
positions = Ledger::Sdk.Container(42).positions.list

# Look up positions across every container — filters[code] is required,
# the root endpoint returns [] without it
positions = Ledger::Sdk.Position.list { { filters: { code: 'FR0000120271' } } }

Inventories

# List inventories of a position
inventories = Ledger::Sdk.Container(42).accounts(7).positions(3).inventories.list

Chaining associations

Models support association chaining from container down to inventory:

# Container -> Accounts -> Positions -> Inventories
Ledger::Sdk.Container(42).accounts(7).positions(3).inventories.list

Positions, inventories, and balances have no individual show endpoint: their data is returned by list (calling data on a bare chained instance raises NotImplementedError).

Error handling

The SDK raises the fluence-gateway-client errors as-is:

begin
  Ledger::Sdk.Container.list
rescue Fluence::Gateway::AuthenticationError
  # OAuth2 credentials invalid — check APPCENTER_CLIENT_ID / APPCENTER_CLIENT_SECRET
rescue Fluence::Gateway::ConnectionError
  # Gateway unreachable — safe to retry with backoff
rescue Fluence::Gateway::RequestError => e
  # Ledger responded 4xx/5xx — e.status, e.body, e.headers are available
end

Development

After checking out the repo, run bin/setup to install dependencies.

Use bin/console for an interactive prompt with the SDK pre-loaded. Set the APPCENTER_CLIENT_ID and APPCENTER_CLIENT_SECRET environment variables (read directly by fluence-gateway-client) before launching:

APPCENTER_CLIENT_ID=your_id APPCENTER_CLIENT_SECRET=your_secret bin/console

Run the full catalog (lint + security + codequality + tests) with:

bundle exec fluence-ci all

License

The gem is available as open source under the terms of the MIT License.