105 lines
2.9 KiB
Markdown
105 lines
2.9 KiB
Markdown
# API: hyper-p2p-credit-ledger
|
|
|
|
**Protocol:** `credit-ledger/v1`
|
|
|
|
**Export:** `{ HyperP2PCreditLedger, PROTOCOL }`
|
|
|
|
## Overview
|
|
|
|
`HyperP2PCreditLedger` provides gossip-synchronized account balances. Each account holds a numeric `balance`; `credit`, `debit`, and `transfer` update local state and emit `ledger-entry` gossip with the **authoritative balance** after each mutation (not operation logs).
|
|
|
|
Extends `bare-events` `EventEmitter`.
|
|
|
|
## Constructor
|
|
|
|
```js
|
|
const { HyperP2PCreditLedger } = require('hyper-p2p-credit-ledger')
|
|
const ledger = new HyperP2PCreditLedger(opts)
|
|
```
|
|
|
|
| Option | Type | Default | Description |
|
|
|--------|------|---------|-------------|
|
|
| `topic` | `string` \| `Buffer` | `null` | Hyperswarm topic |
|
|
| `keyPair` | `KeyPair` | random | Signing identity; `peerHex` on entries |
|
|
|
|
## Lifecycle
|
|
|
|
### `async ready() → HyperP2PCreditLedger`
|
|
|
|
Initializes swarm when `topic` set.
|
|
|
|
### `async close() → void`
|
|
|
|
Destroys swarm; clears `_accounts`.
|
|
|
|
### `getStats() → object`
|
|
|
|
`{ credits, debits, gossipIn, gossipOut, accounts, protocol }`.
|
|
|
|
## Methods
|
|
|
|
### `openAccount(accountId, initial = 0) → account`
|
|
|
|
Creates account; gossips `ledger-entry` with `kind: 'open'`.
|
|
|
|
- **Returns:** `{ id, balance, updatedAt }`
|
|
- **Throws:** `Error: account exists`
|
|
|
|
### `credit(accountId, amount, reason = '') → account`
|
|
|
|
Adds `Math.abs(amount)` to balance; `kind: 'credit'`.
|
|
|
|
### `debit(accountId, amount, reason = '') → account`
|
|
|
|
Subtracts `Math.abs(amount)`; `kind: 'debit'`.
|
|
|
|
### `transfer(fromId, toId, amount) → { from, to, amount, at }`
|
|
|
|
Atomic pair: debit then credit with linked reasons.
|
|
|
|
- **Throws:** `unknown account`, `insufficient balance`, `amount must be positive`
|
|
|
|
### `balance(accountId) → number | null`
|
|
|
|
Current balance or `null` if unknown.
|
|
|
|
## Account gossip entry
|
|
|
|
Remote handler applies **balance snapshot** from gossip (not replay of deltas):
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `type` | `'ledger-entry'` | Fixed discriminator |
|
|
| `accountId` | `string` | Account key |
|
|
| `kind` | `'open' \| 'credit' \| 'debit'` | Mutation class |
|
|
| `balance` | `number` | Balance after operation |
|
|
| `at` | `number` | Timestamp ms |
|
|
| `delta` | `number` | Optional; present on credit/debit |
|
|
| `reason` | `string` | Optional note |
|
|
| `peer` | `string` | Hex pubkey of originator |
|
|
|
|
## Events
|
|
|
|
| Event | When | Payload |
|
|
|-------|------|---------|
|
|
| `account` | `openAccount` | account |
|
|
| `credit` | `credit()` | `{ accountId, balance, delta, reason }` |
|
|
| `debit` | `debit()` | same shape |
|
|
| `remote-entry` | inbound gossip | full ledger-entry |
|
|
|
|
## Errors
|
|
|
|
`account exists`, `unknown account`, `insufficient balance`, `amount must be positive`, `assertNonEmpty` on ids.
|
|
|
|
## P2P
|
|
|
|
Single wire type `ledger-entry`. New accounts created on remote `kind === 'open'`; updates overwrite `balance` when account exists.
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
npm install && npm test
|
|
```
|
|
|
|
Example: [`../examples/basic.js`](../examples/basic.js).
|