URI-to-Balance Mapping System for Distributed Ledgers
Web Ledgers provides a standardized method for mapping Uniform Resource Identifiers (URIs) to numerical balances on the web, enabling distributed ledger systems that transcend platform boundaries.
Web Ledgers enable seamless value transfer between heterogeneous systems including:
- Social platforms (GitHub, Twitter, YouTube)
- Blockchain networks (Bitcoin addresses, transaction outputs)
- Communication protocols (email, phone)
- Decentralized identity systems (WebID, Nostr DIDs)
- Custom applications (gaming, reputation, carbon credits)
- Universal Identifiers: Uses URIs for cross-platform compatibility
- Multi-Currency Support: Flexible amount formats for different currencies
- JSON-LD Compliance: Structured data with semantic web compatibility
- Interactive CLI: Beautiful command-line interface with wizards
- Well-Known Convention: Follows RFC 5785 for standard file locations
- Validation System: Comprehensive validation with warnings and errors
- Extensible Format: Support for custom currencies and metadata
npm install webledgersFor global CLI access:
npm install -g webledgersA Web Ledger is a JSON-LD document that maps URIs to balances:
{
"@context": "https://w3id.org/webledgers",
"type": "WebLedger",
"id": "https://example.com/ledger/1",
"name": "Universal Web Credits",
"description": "Cross-platform ledger for web credits",
"defaultCurrency": "satoshi",
"created": 1705276800,
"updated": 1705316200,
"entries": [
{
"type": "Entry",
"url": "https://github.com/user#this",
"amount": "100000"
},
{
"type": "Entry",
"url": "did:nostr:de7ecd1e2976a6adb2ffa5f4db81a7d812c8bb6698aa00dcf1e76adb55efd645",
"amount": [
{ "currency": "satoshi", "value": "50000" },
{ "currency": "USD", "value": "25.00" }
]
}
]
}Simple String Format (single currency):
{
"url": "https://github.com/user#this",
"amount": "100000"
}Multi-Currency Array Format:
{
"url": "https://example.com/profile#me",
"amount": [
{ "currency": "satoshi", "value": "50000" },
{ "currency": "USD", "value": "25.00" },
{ "currency": "points", "value": "1000" }
]
}Web Ledgers follow RFC 5785 well-known URI conventions:
project/
βββ .well-known/
β βββ webledgers/
β βββ webledgers.json β Default location
βββ cli.js
βββ index.js
βββ package.json
# Interactive mode - full featured workflow
webledgers interactive
# Create a new ledger
webledgers create
# Add entries to existing ledger
webledgers add
# View all balances
webledgers balance
# Query specific balance interactively
webledgers query
# Show complete ledger with metadata
webledgers show
# Validate ledger structure
webledgers validateCreate a new ledger with interactive wizard.
Options:
-o, --output <file>- Output file (default:.well-known/webledgers/webledgers.json)
Example:
webledgers create -o my-ledger.jsonAdd entries to an existing ledger.
Arguments:
file- Ledger file path (optional, defaults to well-known location)
Options:
-f, --file <file>- Ledger file path
Example:
webledgers add
webledgers add my-ledger.jsonDisplay all balances in the ledger.
Arguments:
file- Ledger file path (optional)
Options:
-f, --file <file>- Ledger file path-c, --currency <currency>- Filter by specific currency
Examples:
webledgers balance # Show all balances
webledgers balance -c USD # Show only USD balances
webledgers balance my-ledger.json # Use specific fileInteractive balance query for specific URI.
Arguments:
file- Ledger file path (optional)
Options:
-f, --file <file>- Ledger file path
Example:
webledgers queryDisplay complete ledger contents with metadata.
Arguments:
file- Ledger file path (optional)
Options:
-f, --file <file>- Ledger file path-c, --currency <currency>- Currency for totals display
Example:
webledgers show -c satoshiValidate ledger structure and data.
Arguments:
file- Ledger file path (optional)
Options:
-f, --file <file>- Ledger file path
Example:
webledgers validateCalculate total balances by currency.
Arguments:
file- Ledger file path (optional)
Options:
-f, --file <file>- Ledger file path-c, --currency <currency>- Specific currency (shows all if not specified)
Examples:
webledgers total # Show all currency totals
webledgers total -c USD # Show USD total onlySearch entries by criteria (interactive if no criteria specified).
Arguments:
file- Ledger file path (optional)
Options:
-f, --file <file>- Ledger file path--url <pattern>- URL pattern to search for--min-amount <amount>- Minimum amount--max-amount <amount>- Maximum amount-c, --currency <currency>- Currency for amount filters
Examples:
webledgers search # Interactive search
webledgers search --url "github" # Find GitHub entries
webledgers search --min-amount "1000" -c satoshi # Find entries with >1000 satoshiMerge two ledgers.
Options:
-a, --first <file>- First ledger file (default: well-known path)-b, --second <file>- Second ledger file (required)-o, --output <file>- Output file (default: well-known path)-s, --strategy <strategy>- Conflict strategy:replace|add|skip(default:replace)
Example:
webledgers merge -b other-ledger.json -s addFull interactive mode with guided workflows.
Alias: webledgers i
Example:
webledgers interactiveconst { WebLedger, createLedger, loadLedger } = require('webledgers')
// Create a new ledger
const ledger = createLedger({
name: 'My Ledger',
description: 'A ledger for tracking web credits',
defaultCurrency: 'satoshi'
})
// Add entries
ledger.addEntry('https://github.com/user#this', '100000')
ledger.addEntry('mailto:user@example.com', [
{ currency: 'USD', value: '50.00' },
{ currency: 'points', value: '1000' }
])
// Query balances
const balance = ledger.getBalance('https://github.com/user#this')
console.log(balance) // "100000"
const usdBalance = ledger.getBalance('mailto:user@example.com', 'USD')
console.log(usdBalance) // "50.00"
// Get totals
const totalSatoshi = ledger.getTotalBalance('satoshi')
const totalUSD = ledger.getTotalBalance('USD')
// Validate
const validation = ledger.validate()
if (validation.isValid) {
console.log('β
Ledger is valid')
} else {
console.log('β Validation errors:', validation.errors)
}
// Save to JSON-LD
const jsonData = ledger.toJSON(true) // pretty printedconst ledger = new WebLedger(options)Options:
context- JSON-LD context URIid- Ledger identifier URIname- Human-readable ledger namedescription- Ledger descriptiondefaultCurrency- Default currency codecreated- Creation timestampupdated- Last update timestamp
// Add or update entry
const entry = ledger.addEntry(uri, amount)
// Remove entry
const removed = ledger.removeEntry(uri)
// Get specific entry
const entry = ledger.getEntry(uri)
// Update balance
const updated = ledger.updateBalance(uri, newAmount)// Get balance for specific currency
const balance = ledger.getBalance(uri, currency)
// Get total for currency
const total = ledger.getTotalBalance(currency)
// Count entries
const count = ledger.getEntryCount()
// Find entries by criteria
const results = ledger.findEntries({
url: 'github',
minAmount: '1000',
currency: 'satoshi'
})// Validate entire ledger
const validation = ledger.validate()
// Returns: { isValid: boolean, errors: string[], warnings: string[] }
// Validate single entry
const entryValidation = ledger.validateEntry(entry)// Export to JSON-LD
const json = ledger.toJSON(pretty)
// Load from data
const ledger = loadLedger(jsonData)// Merge with another ledger
ledger.merge(otherLedger, 'replace') // 'replace', 'add', or 'skip'
// URI validation
const isValid = ledger.isValidURI(uri)const {
createLedger,
loadLedger,
validateLedgerData,
generateLedgerId
} = require('webledgers')
// Create new ledger
const ledger = createLedger(options)
// Load from JSON data
const ledger = loadLedger(jsonData)
// Validate without creating instance
const validation = validateLedgerData(rawData)
// Generate unique ID
const id = generateLedgerId(){
"@context": "https://w3id.org/webledgers",
"type": "WebLedger",
"name": "Social Platform Credits",
"defaultCurrency": "points",
"entries": [
{
"type": "Entry",
"url": "https://github.com/alice#this",
"amount": "2500"
},
{
"type": "Entry",
"url": "https://twitter.com/bob#this",
"amount": "1200"
}
]
}{
"@context": "https://w3id.org/webledgers",
"type": "WebLedger",
"name": "Gaming Tournament Rewards",
"defaultCurrency": "coins",
"entries": [
{
"type": "Entry",
"url": "did:nostr:abc123...",
"amount": [
{ "currency": "coins", "value": "1000" },
{ "currency": "gems", "value": "50" }
]
}
]
}{
"@context": "https://w3id.org/webledgers",
"type": "WebLedger",
"name": "Bitcoin Holdings",
"defaultCurrency": "satoshi",
"entries": [
{
"type": "Entry",
"url": "bitcoin:1Kr6QSydW9bFQG1mXiPNNu6WpJGmUa9i1g",
"amount": "2100000"
},
{
"type": "Entry",
"url": "txo:btc:f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16:0",
"amount": "5000000000"
}
]
}{
"@context": "https://w3id.org/webledgers",
"type": "WebLedger",
"name": "Developer Reputation",
"defaultCurrency": "reputation-points",
"entries": [
{
"type": "Entry",
"url": "https://github.com/developer#this",
"amount": "8500"
},
{
"type": "Entry",
"url": "mailto:dev@example.com",
"amount": "6200"
}
]
}{
"@context": "https://w3id.org/webledgers",
"type": "WebLedger",
"name": "Course Credits",
"defaultCurrency": "credit-hours",
"entries": [
{
"type": "Entry",
"url": "mailto:student@university.edu",
"amount": "120"
}
]
}Web Ledgers include comprehensive validation with both errors and warnings:
Errors (prevent ledger from being valid):
- Missing required fields (
entriesarray) - Invalid URI formats
- Malformed amount values
- Invalid currency objects
Warnings (recommended but not required):
- Missing
@contextfield - Missing
typefield - Missing entry type fields
β
Ledger is valid!
β οΈ Warnings:
β’ Missing @context field (recommended for JSON-LD compliance)
β’ Entry 0: Missing or invalid type field (recommended for JSON-LD compliance)Web Ledgers support any valid URI scheme, including:
- HTTP/HTTPS:
https://example.com/profile#me - WebID:
https://person.example.com/card#i - Email:
mailto:user@example.com - Phone:
tel:+15550123456 - Bitcoin:
bitcoin:1Kr6QSydW9bFQG1mXiPNNu6WpJGmUa9i1g - Nostr DID:
did:nostr:abc123... - Custom URNs:
urn:voucher:xyz789 - Social Platforms:
https://github.com/user#this
- WebLedger Class - Main ledger management
- Entry Class - Individual URI-balance mappings
- CLI Tool - Interactive command-line interface
- Validation System - Comprehensive structure validation
- Serialization - JSON-LD export/import
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β JSON-LD β β WebLedger β β CLI/API β
β Data βββββΊβ Instance βββββΊβ Interface β
β β β β β β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β² β² β²
β β β
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β File System β β Validation β β User Input β
β Storage β β System β β Wizards β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
npm install -g webledgerswebledgers createFollow the interactive wizard to set up your ledger.
webledgers addUse the entry wizard to add URI-balance mappings.
webledgers balanceSee all balances in a beautiful table format.
webledgers --helpThe complete Web Ledgers specification is available at: https://solidpayorg.github.io/webledgers/
The specification defines:
- JSON-LD data models
- Serialization formats
- Interoperability guidelines
- URI scheme support
- Multi-currency handling
We welcome contributions! Please see our contributing guidelines:
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes with tests
- Run validation:
npm test - Commit changes:
git commit -m "Add feature" - Push to branch:
git push origin feature-name - Create Pull Request
git clone https://github.com/solidpayorg/webledgers.git
cd webledgers
npm install
./cli.js --helpMIT License - see LICENSE file for details.
- Homepage: https://solidpayorg.github.io/webledgers/
- Repository: https://github.com/solidpayorg/webledgers
- Issues: https://github.com/solidpayorg/webledgers/issues
- NPM Package: https://www.npmjs.com/package/webledgers
- Discussions: GitHub Discussions
- Issues: GitHub Issues
- W3C Community: Web Payments Community Group
Web Ledgers - Making the web a ledger, one URI at a time. ππ°