monetra 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -156
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,245 +1,286 @@
|
|
|
1
1
|
# Monetra
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Monetra is a TypeScript-first, zero-dependency money engine built for applications where every cent matters. It eliminates floating-point errors, enforces explicit rounding, and provides built-in audit trails—making it ideal for fintech, e-commerce, accounting, and cryptocurrency applications.
|
|
3
|
+
A TypeScript library for handling monetary values with precision.
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/monetra)
|
|
8
|
-

|
|
12
|
-
|
|
13
|
-
## Why Monetra?
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://www.typescriptlang.org/)
|
|
8
|
+
[]()
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
// ❌ Regular JavaScript
|
|
17
|
-
0.1 + 0.2 === 0.3 // false! (0.30000000000000004)
|
|
18
|
-
|
|
19
|
-
// ✅ Monetra
|
|
20
|
-
Money.fromDecimal('0.10', 'USD').add('0.20').equals('0.30') // true
|
|
21
|
-
```
|
|
10
|
+
---
|
|
22
11
|
|
|
23
|
-
|
|
12
|
+
## Overview
|
|
24
13
|
|
|
25
|
-
|
|
14
|
+
Monetra is a zero-dependency TypeScript library that handles monetary values using integer arithmetic. By storing amounts in minor units (cents, satoshis, wei) as `BigInt`, it avoids the floating-point precision errors inherent in JavaScript's `number` type.
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
## Features
|
|
16
|
+
```typescript
|
|
17
|
+
// JavaScript floating-point issue
|
|
18
|
+
0.1 + 0.2 === 0.3; // false (0.30000000000000004)
|
|
32
19
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
| 🌍 **Multi-Currency** | ISO 4217 currencies + custom tokens + crypto (18 decimals) |
|
|
38
|
-
| 📊 **Financial Math** | Loan payments, NPV, IRR, amortization schedules |
|
|
39
|
-
| 📝 **Audit Ledger** | Tamper-evident transaction history with SHA-256 hashing |
|
|
40
|
-
| 🔄 **Currency Conversion** | Rate management with historical lookups |
|
|
41
|
-
| 💼 **Wallet/MoneyBag** | Multi-currency portfolio management |
|
|
42
|
-
| ⚡ **Zero Dependencies** | Nothing to audit, nothing to break |
|
|
43
|
-
| 🌐 **Runs Everywhere** | Node.js, browsers, serverless, edge functions |
|
|
44
|
-
|
|
45
|
-
## Table of Contents
|
|
46
|
-
|
|
47
|
-
- [Quick Start](#quick-start)
|
|
48
|
-
- [Core Concepts](#core-concepts)
|
|
49
|
-
- [Usage Examples](#usage-examples)
|
|
50
|
-
- [What's New in v2.0](#whats-new-in-v20)
|
|
51
|
-
- [Documentation](#documentation)
|
|
52
|
-
- [Testing](#testing)
|
|
53
|
-
- [Contributing](#contributing)
|
|
54
|
-
- [Security](#security)
|
|
55
|
-
- [License](#license)
|
|
20
|
+
// Monetra
|
|
21
|
+
import { money } from "monetra";
|
|
22
|
+
money("0.10", "USD").add("0.20").equals(money("0.30", "USD")); // true
|
|
23
|
+
```
|
|
56
24
|
|
|
57
|
-
|
|
25
|
+
---
|
|
58
26
|
|
|
59
|
-
|
|
27
|
+
## Installation
|
|
60
28
|
|
|
61
29
|
```bash
|
|
62
30
|
npm install monetra
|
|
63
|
-
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
64
34
|
yarn add monetra
|
|
65
|
-
# or
|
|
66
|
-
pnpm add monetra
|
|
67
35
|
```
|
|
68
36
|
|
|
69
|
-
|
|
37
|
+
```bash
|
|
38
|
+
pnpm add monetra
|
|
39
|
+
```
|
|
70
40
|
|
|
71
|
-
|
|
72
|
-
import { money, USD } from "monetra";
|
|
41
|
+
**Requirements:** Node.js 18+ or modern browsers with BigInt support.
|
|
73
42
|
|
|
74
|
-
|
|
75
|
-
const price = money("10.50", "USD"); // $10.50
|
|
76
|
-
const tax = price.percentage(10); // $1.05
|
|
43
|
+
---
|
|
77
44
|
|
|
78
|
-
|
|
79
|
-
const total = price.add(tax); // $11.55
|
|
80
|
-
const discounted = total.subtract("2.00"); // $9.55
|
|
45
|
+
## Features
|
|
81
46
|
|
|
82
|
-
|
|
83
|
-
|
|
47
|
+
- **Integer-based storage** - All values stored as `BigInt` in minor units
|
|
48
|
+
- **Explicit rounding** - Six rounding modes (HALF_UP, HALF_DOWN, HALF_EVEN, FLOOR, CEIL, TRUNCATE)
|
|
49
|
+
- **Currency support** - ISO 4217 currencies with automatic precision handling
|
|
50
|
+
- **Custom tokens** - Define cryptocurrencies and tokens with up to 18 decimal places
|
|
51
|
+
- **Allocation** - Split amounts without losing cents
|
|
52
|
+
- **Financial calculations** - Compound interest, loan amortization, NPV, IRR
|
|
53
|
+
- **Ledger** - Append-only transaction log with hash chain verification
|
|
54
|
+
- **Currency conversion** - Rate management with historical lookups
|
|
55
|
+
- **Multi-currency** - MoneyBag for aggregating different currencies
|
|
56
|
+
- **Immutable** - All operations return new instances
|
|
57
|
+
- **Type-safe** - Full TypeScript support with strict types
|
|
84
58
|
|
|
85
|
-
|
|
59
|
+
---
|
|
86
60
|
|
|
87
|
-
|
|
61
|
+
## Quick Start
|
|
88
62
|
|
|
89
|
-
|
|
63
|
+
### Basic Usage
|
|
90
64
|
|
|
91
|
-
|
|
92
|
-
|
|
65
|
+
```typescript
|
|
66
|
+
import { money, Money, RoundingMode } from "monetra";
|
|
93
67
|
|
|
94
|
-
|
|
68
|
+
// Create money from string (major units)
|
|
69
|
+
const price = money("19.99", "USD");
|
|
95
70
|
|
|
96
|
-
|
|
71
|
+
// Create from minor units (cents)
|
|
72
|
+
const tax = Money.fromMinor(199, "USD");
|
|
97
73
|
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
const
|
|
74
|
+
// Arithmetic
|
|
75
|
+
const subtotal = price.add(tax);
|
|
76
|
+
const total = subtotal.multiply(2);
|
|
101
77
|
|
|
102
|
-
|
|
103
|
-
console.log(
|
|
78
|
+
// Formatting
|
|
79
|
+
console.log(total.format()); // "$43.96"
|
|
80
|
+
console.log(total.format({ locale: "de-DE" })); // "43,96 $"
|
|
104
81
|
```
|
|
105
82
|
|
|
106
|
-
###
|
|
83
|
+
### Allocation
|
|
107
84
|
|
|
108
|
-
|
|
85
|
+
Split money without losing cents:
|
|
109
86
|
|
|
110
87
|
```typescript
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
```
|
|
88
|
+
const bill = money("100.00", "USD");
|
|
89
|
+
const shares = bill.split(3);
|
|
90
|
+
// [money("33.34"), money("33.33"), money("33.33")]
|
|
115
91
|
|
|
116
|
-
|
|
92
|
+
// Verify sum equals original
|
|
93
|
+
shares.reduce((a, b) => a.add(b)).equals(bill); // true
|
|
94
|
+
```
|
|
117
95
|
|
|
118
|
-
###
|
|
96
|
+
### Rounding
|
|
119
97
|
|
|
120
|
-
|
|
98
|
+
Operations that produce fractional minor units require explicit rounding:
|
|
121
99
|
|
|
122
100
|
```typescript
|
|
123
|
-
const
|
|
124
|
-
|
|
101
|
+
const price = money("100.00", "USD");
|
|
102
|
+
|
|
103
|
+
// Division requires rounding mode
|
|
104
|
+
const third = price.divide(3, { rounding: RoundingMode.HALF_UP });
|
|
105
|
+
console.log(third.format()); // "$33.33"
|
|
125
106
|
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
//
|
|
129
|
-
// Sum: $100.00
|
|
107
|
+
// Or use allocate for lossless division
|
|
108
|
+
const parts = price.allocate([1, 1, 1]);
|
|
109
|
+
// ["$33.34", "$33.33", "$33.33"]
|
|
130
110
|
```
|
|
131
111
|
|
|
132
|
-
|
|
112
|
+
### Custom Tokens
|
|
133
113
|
|
|
134
|
-
|
|
114
|
+
Define cryptocurrencies or custom tokens:
|
|
135
115
|
|
|
136
116
|
```typescript
|
|
137
|
-
|
|
138
|
-
Money.fromCents(1000, 'USD'); // Same as fromMinor
|
|
139
|
-
Money.fromDecimal('10.50', 'USD'); // Same as fromMajor
|
|
117
|
+
import { defineToken, money } from "monetra";
|
|
140
118
|
|
|
141
|
-
|
|
142
|
-
|
|
119
|
+
const USDC = defineToken({
|
|
120
|
+
code: "USDC",
|
|
121
|
+
symbol: "USDC",
|
|
122
|
+
decimals: 6,
|
|
123
|
+
type: "crypto",
|
|
124
|
+
});
|
|
143
125
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// JSON serialization support
|
|
148
|
-
const json = JSON.stringify(money);
|
|
149
|
-
const restored = JSON.parse(json, Money.reviver);
|
|
126
|
+
const balance = money("1000.50", USDC);
|
|
127
|
+
console.log(balance.format()); // "1,000.50 USDC"
|
|
150
128
|
```
|
|
151
129
|
|
|
152
|
-
###
|
|
130
|
+
### Financial Calculations
|
|
153
131
|
|
|
154
132
|
```typescript
|
|
155
|
-
money
|
|
133
|
+
import { money, futureValue, pmt, loan } from "monetra";
|
|
134
|
+
|
|
135
|
+
// Future value of investment
|
|
136
|
+
const principal = money("10000", "USD");
|
|
137
|
+
const future = futureValue(principal, {
|
|
138
|
+
rate: 0.07,
|
|
139
|
+
years: 10,
|
|
140
|
+
compoundingPerYear: 12,
|
|
141
|
+
});
|
|
142
|
+
console.log(future.format()); // "$20,096.61"
|
|
143
|
+
|
|
144
|
+
// Monthly loan payment
|
|
145
|
+
const payment = pmt({
|
|
146
|
+
principal: money("200000", "USD"),
|
|
147
|
+
annualRate: 0.065,
|
|
148
|
+
years: 30,
|
|
149
|
+
});
|
|
150
|
+
console.log(payment.format()); // "$1,264.14"
|
|
156
151
|
```
|
|
157
152
|
|
|
158
|
-
###
|
|
153
|
+
### Ledger
|
|
154
|
+
|
|
155
|
+
Track transactions with verification:
|
|
159
156
|
|
|
160
157
|
```typescript
|
|
161
|
-
|
|
162
|
-
negative.format({ accounting: true }); // "($100.00)"
|
|
163
|
-
```
|
|
158
|
+
import { Ledger, money } from "monetra";
|
|
164
159
|
|
|
165
|
-
|
|
160
|
+
const ledger = new Ledger("USD");
|
|
166
161
|
|
|
167
|
-
|
|
168
|
-
|
|
162
|
+
ledger.credit("account", money("1000.00", "USD"), "Deposit");
|
|
163
|
+
ledger.debit("account", money("50.00", "USD"), "Purchase");
|
|
169
164
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const effective = annual.toEffective(12); // ~12.68%
|
|
165
|
+
console.log(ledger.getBalance("account").format()); // "$950.00"
|
|
166
|
+
console.log(ledger.verify()); // true
|
|
173
167
|
```
|
|
174
168
|
|
|
175
|
-
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## API Summary
|
|
172
|
+
|
|
173
|
+
### Money Class
|
|
174
|
+
|
|
175
|
+
| Method | Description |
|
|
176
|
+
| ----------------------------------- | ------------------------------------ |
|
|
177
|
+
| `money(amount, currency)` | Create Money from string or number |
|
|
178
|
+
| `Money.fromMinor(cents, currency)` | Create from minor units |
|
|
179
|
+
| `Money.fromMajor(amount, currency)` | Create from major units (string) |
|
|
180
|
+
| `Money.zero(currency)` | Create zero amount |
|
|
181
|
+
| `.add(other)` | Add two Money values |
|
|
182
|
+
| `.subtract(other)` | Subtract Money values |
|
|
183
|
+
| `.multiply(factor, options?)` | Multiply by scalar |
|
|
184
|
+
| `.divide(divisor, options)` | Divide by scalar (requires rounding) |
|
|
185
|
+
| `.percentage(percent, rounding?)` | Calculate percentage |
|
|
186
|
+
| `.split(n)` | Split into n equal parts |
|
|
187
|
+
| `.allocate(ratios)` | Allocate by ratios |
|
|
188
|
+
| `.format(options?)` | Format for display |
|
|
189
|
+
| `.equals(other)` | Check equality |
|
|
190
|
+
| `.lessThan(other)` | Compare values |
|
|
191
|
+
| `.greaterThan(other)` | Compare values |
|
|
192
|
+
| `.isPositive()` | Check if positive |
|
|
193
|
+
| `.isNegative()` | Check if negative |
|
|
194
|
+
| `.isZero()` | Check if zero |
|
|
195
|
+
|
|
196
|
+
### Financial Functions
|
|
197
|
+
|
|
198
|
+
| Function | Description |
|
|
199
|
+
| ----------------------------------------- | --------------------------------------------- |
|
|
200
|
+
| `futureValue(principal, options)` | Calculate future value with compound interest |
|
|
201
|
+
| `presentValue(futureAmount, options)` | Calculate present value |
|
|
202
|
+
| `pmt(options)` | Calculate loan payment amount |
|
|
203
|
+
| `loan(options)` | Generate amortization schedule |
|
|
204
|
+
| `npv(initialInvestment, cashFlows, rate)` | Net present value |
|
|
205
|
+
| `irr(initialInvestment, cashFlows)` | Internal rate of return |
|
|
206
|
+
|
|
207
|
+
### Classes
|
|
208
|
+
|
|
209
|
+
| Class | Description |
|
|
210
|
+
| ----------- | --------------------------------------------- |
|
|
211
|
+
| `Ledger` | Append-only transaction log with verification |
|
|
212
|
+
| `Converter` | Currency conversion with rate management |
|
|
213
|
+
| `MoneyBag` | Multi-currency aggregation |
|
|
214
|
+
|
|
215
|
+
---
|
|
176
216
|
|
|
177
|
-
|
|
178
|
-
const converter = new Converter('USD', { EUR: 0.92 });
|
|
179
|
-
converter.addHistoricalRate('EUR', 0.85, new Date('2024-01-01'));
|
|
180
|
-
converter.convert(money, 'EUR', { date: new Date('2024-06-01') });
|
|
181
|
-
```
|
|
217
|
+
## Documentation
|
|
182
218
|
|
|
183
|
-
|
|
219
|
+
Full documentation is available in the [docs](docs/index.md) directory:
|
|
184
220
|
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
usd.add(eur);
|
|
188
|
-
} catch (error) {
|
|
189
|
-
if (error.code === MonetraErrorCode.CURRENCY_MISMATCH) {
|
|
190
|
-
// Handle programmatically
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
```
|
|
221
|
+
**Getting Started**
|
|
194
222
|
|
|
195
|
-
|
|
223
|
+
- [Installation & Setup](docs/getting-started.md)
|
|
224
|
+
- [Core Concepts](docs/core-concepts.md)
|
|
196
225
|
|
|
197
|
-
|
|
198
|
-
// Async methods for browser environments
|
|
199
|
-
const entry = await ledger.recordAsync(money, metadata);
|
|
200
|
-
const isValid = await ledger.verifyAsync();
|
|
201
|
-
```
|
|
226
|
+
**API Reference**
|
|
202
227
|
|
|
203
|
-
|
|
228
|
+
- [Money](docs/api/money.md) - Core monetary value class
|
|
229
|
+
- [Ledger](docs/api/ledger.md) - Transaction log with verification
|
|
230
|
+
- [Financial](docs/api/financial.md) - Financial calculations
|
|
231
|
+
- [Currency & Tokens](docs/api/currency.md) - Currency and token definitions
|
|
204
232
|
|
|
205
|
-
|
|
233
|
+
**Guides**
|
|
206
234
|
|
|
207
|
-
|
|
235
|
+
- [Allocation & Splitting](docs/guides/allocation.md)
|
|
236
|
+
- [Formatting & Parsing](docs/guides/formatting.md)
|
|
237
|
+
- [Custom Tokens](docs/guides/custom-tokens.md)
|
|
238
|
+
- [Error Handling](docs/guides/error-handling.md)
|
|
208
239
|
|
|
209
|
-
|
|
210
|
-
1. [Core Concepts](docs/001-CORE-CONCEPTS.md) - Fundamental principles and design decisions
|
|
211
|
-
2. [Ledger System](docs/002-LEDGER-SYSTEM.md) - Audit trails and transaction history
|
|
212
|
-
3. [Financial Math](docs/003-FINANCIAL-MATH.md) - Loans, investments, and time-value-of-money
|
|
213
|
-
4. [Tokens & Crypto](docs/004-TOKENS-AND-CRYPTO.md) - Cryptocurrency and custom token support
|
|
214
|
-
5. [API Reference](docs/005-API-REFERENCE.md) - Complete API documentation
|
|
215
|
-
6. [Migration Guide v2.0](docs/006-MIGRATION-v2.md) - Upgrading from v1.x
|
|
216
|
-
7. [Cookbook](docs/007-COOKBOOK.md) - Practical recipes and patterns
|
|
240
|
+
**Framework Examples**
|
|
217
241
|
|
|
218
|
-
|
|
242
|
+
- [React.js](docs/examples/react.md)
|
|
243
|
+
- [Vue.js](docs/examples/vue.md)
|
|
244
|
+
- [Node.js](docs/examples/node.md)
|
|
245
|
+
|
|
246
|
+
**Reference**
|
|
247
|
+
|
|
248
|
+
- [Best Practices](docs/best-practices.md)
|
|
249
|
+
- [Library Comparison](docs/comparison.md)
|
|
219
250
|
|
|
220
|
-
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Testing
|
|
221
254
|
|
|
222
255
|
```bash
|
|
223
|
-
# Run
|
|
256
|
+
# Run tests
|
|
224
257
|
npm test
|
|
225
258
|
|
|
226
|
-
#
|
|
259
|
+
# Watch mode
|
|
227
260
|
npm run test:watch
|
|
228
261
|
|
|
229
|
-
#
|
|
262
|
+
# Coverage report
|
|
230
263
|
npm run test:coverage
|
|
231
264
|
```
|
|
232
265
|
|
|
266
|
+
---
|
|
267
|
+
|
|
233
268
|
## Contributing
|
|
234
269
|
|
|
235
|
-
|
|
270
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
236
271
|
|
|
237
|
-
|
|
272
|
+
Check our [Project Roadmap](https://github.com/users/zugobite/projects/2) to see what we're working on.
|
|
273
|
+
|
|
274
|
+
Please review our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
|
|
275
|
+
|
|
276
|
+
---
|
|
238
277
|
|
|
239
278
|
## Security
|
|
240
279
|
|
|
241
|
-
|
|
280
|
+
Report security vulnerabilities according to our [Security Policy](SECURITY.md).
|
|
281
|
+
|
|
282
|
+
---
|
|
242
283
|
|
|
243
284
|
## License
|
|
244
285
|
|
|
245
|
-
|
|
286
|
+
MIT - see [LICENSE](LICENSE) for details.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monetra",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A currency-aware, integer-based money engine designed for financial correctness. Zero dependencies, TypeScript-first, auditable ledger support.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|