@forgesworn/moneyer 0.2.1 → 0.3.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.1] - 2026-08-22
4
+
5
+ - **Rounding the fee to a whole sat now really is the default.** 0.3.0
6
+ documented `roundFeeToSat` as on unless turned off, and made it so for a
7
+ mint started from the CLI, where the environment reader fills the
8
+ default in. A mint built by calling `createMoneyer` with a config object
9
+ passes the field through as absent, and the server read absent as off -
10
+ so an embedder got a mint that kept fractions of a sat while the same
11
+ mint from the binary rounded them away. Absent now means on in both,
12
+ and only an explicit `false` opts out.
13
+
14
+ It hid because every test that cared about rounding set the flag
15
+ explicitly, so nothing exercised the default through the library at all.
16
+ Found from the other side: notecase's cross-implementation suite began
17
+ asserting what a wallet is actually credited, and the mint it builds in
18
+ process disagreed with the mint on the wire.
19
+
20
+ ## [0.3.0] - 2026-08-22
21
+
22
+ - **The mint fee is now ceilinged to a whole sat by default.**
23
+ `MONEYER_ROUND_FEE_TO_SAT` defaults to `true`, matching dni's
24
+ lnurl-mint, the reference. **An operator upgrading into this withholds
25
+ slightly more per mint than before** - up to one sat, whatever the ppm
26
+ cut worked out to - so it is called out here rather than changed
27
+ quietly. `MONEYER_ROUND_FEE_TO_SAT=false` restores the old behaviour.
28
+
29
+ Why: a mint that deals in fractions of a sat issues notes nothing
30
+ downstream can spend. An msat-exact fee makes notes like 94.9 sat, and
31
+ most Lightning wallets can only invoice whole sats, so such a note
32
+ cannot be withdrawn by them at all. The mint already covered that by
33
+ advertising `minWithdrawable` as the whole-sat floor and keeping the
34
+ remainder as dust; rounding at mint time means it never arises. Every
35
+ note this mint issues for a whole-sat payment is now worth a whole
36
+ number of sats, on both the pay callback and the zap path, which share
37
+ one fee function.
38
+
39
+ LUD-25 says nothing about rounding and `lnurlcash-kit`'s `mintFeeBand`
40
+ accepts either, so this is a posture change and not a compliance one.
41
+ The conformance grader passed both before and passes this now.
42
+
3
43
  ## [0.2.1] - 2026-08-22
4
44
 
5
45
  - `moneyer --dev` settles its invoices a moment after issuing them rather
package/README.md CHANGED
@@ -87,7 +87,7 @@ default, and a variable set to an empty string counts as unset.
87
87
  | `MONEYER_PREVIOUS_SIGNING_PUBKEYS` | | compressed pubkeys this mint signed under before, comma separated (see below) |
88
88
  | `MONEYER_BASE_FEE_MSAT` | `0` | flat mint fee |
89
89
  | `MONEYER_FEE_PPM` | `0` | proportional mint fee, parts per million |
90
- | `MONEYER_ROUND_FEE_TO_SAT` | `false` | ceiling the mint fee to a whole sat (see below) |
90
+ | `MONEYER_ROUND_FEE_TO_SAT` | `true` | ceiling the mint fee to a whole sat (see below) |
91
91
  | `MONEYER_MIN_SENDABLE_MSAT` | `1000` | smallest payment the mint advertises |
92
92
  | `MONEYER_MAX_SENDABLE_MSAT` | `100000000` | largest payment the mint advertises |
93
93
  | `MONEYER_MIN_MINT_MSAT` | `1000` | dust floor: the smallest note the mint will strike |
@@ -269,16 +269,20 @@ the msat-exact amount. Neither is out of spec - lnurlcash-kit's
269
269
  `mintFeeBand` treats anything between the two as the mint keeping its
270
270
  word, and the conformance grader accepts both.
271
271
 
272
- `MONEYER_ROUND_FEE_TO_SAT=true` switches this mint to the reference's
273
- behaviour. Off by default: turning it on raises what the mint withholds,
274
- and that is not a change to make behind an operator's back on a redeploy.
275
-
276
- Why you probably want it on anyway: msat-exact fees make notes like 94.9
277
- sat, and most Lightning wallets can only invoice whole sats, so such a
278
- note cannot be withdrawn by them. moneyer covers the notes already out
279
- there by advertising `minWithdrawable` as the note floored to a whole sat
280
- and accepting a melt for that; the sub-sat remainder is dust the mint
281
- keeps. Rounding at mint time means it never comes up.
272
+ **moneyer rounds, by default.** A mint that deals in fractions of a sat
273
+ issues notes nothing downstream can spend: msat-exact fees make notes like
274
+ 94.9 sat, and most Lightning wallets can only invoice whole sats, so such
275
+ a note cannot be withdrawn by them at all. moneyer covers the notes
276
+ already out there by advertising `minWithdrawable` as the note floored to
277
+ a whole sat and accepting a melt for that, keeping the sub-sat remainder
278
+ as dust - a wart it should not need. Rounding at mint time means it never
279
+ comes up, and every note this mint issues for a whole-sat payment is worth
280
+ a whole number of sats.
281
+
282
+ `MONEYER_ROUND_FEE_TO_SAT=false` restores the msat-exact fee. An operator
283
+ upgrading into this default withholds slightly more per mint than before,
284
+ which is why the changelog says so plainly rather than letting a redeploy
285
+ change it quietly.
282
286
 
283
287
  ## Melting to an invoice with no amount
284
288
 
package/dist/config.d.ts CHANGED
@@ -65,7 +65,7 @@ export declare const DEFAULTS: {
65
65
  readonly verify: true;
66
66
  readonly maxK1s: 21;
67
67
  readonly sunset: false;
68
- readonly roundFeeToSat: false;
68
+ readonly roundFeeToSat: true;
69
69
  readonly stats: true;
70
70
  readonly statsRatioOnly: false;
71
71
  readonly statsPublish: false;
package/dist/config.js CHANGED
@@ -14,7 +14,7 @@ export const DEFAULTS = {
14
14
  verify: true,
15
15
  maxK1s: 21,
16
16
  sunset: false,
17
- roundFeeToSat: false,
17
+ roundFeeToSat: true,
18
18
  stats: true,
19
19
  statsRatioOnly: false,
20
20
  statsPublish: false,
package/dist/server.js CHANGED
@@ -92,7 +92,13 @@ export const createMoneyer = async (config, deps = {}) => {
92
92
  const exact = grossMsat - applyMintFee(grossMsat, config.mintFee);
93
93
  // Both readings sit inside lnurlcash-kit's mintFeeBand, so a wallet
94
94
  // is not misled either way - it is told the range up front.
95
- return config.roundFeeToSat === true ? Math.ceil(exact / 1000) * 1000 : exact;
95
+ //
96
+ // Absent means ON, the same as DEFAULTS and MONEYER_ROUND_FEE_TO_SAT:
97
+ // only an explicit false opts out. Reading it as `=== true` made the
98
+ // library default differ from the binary's, so a mint built by calling
99
+ // createMoneyer kept fractions of a sat that the same mint started from
100
+ // the CLI would have rounded.
101
+ return config.roundFeeToSat !== false ? Math.ceil(exact / 1000) * 1000 : exact;
96
102
  };
97
103
  // Every quote and every credit goes through here, so the fee posture
98
104
  // cannot drift between what is advertised and what is withheld.
@@ -116,7 +122,7 @@ export const createMoneyer = async (config, deps = {}) => {
116
122
  const mintFeeLine = config.mintFee ? `Mint fees: ${config.mintFee.baseFeeMsat},${config.mintFee.feePpm}` : null;
117
123
  // The same fee for a person: "Mint fees: 5000,1000" is for wallets that
118
124
  // parse LUD-25, and reads as nonsense to anyone who does not.
119
- const feeInWords = config.mintFee ? describeFee(config.mintFee, config.roundFeeToSat === true) : null;
125
+ const feeInWords = config.mintFee ? describeFee(config.mintFee, config.roundFeeToSat !== false) : null;
120
126
  const nostr = config.zap ? (deps.nostr ?? poolTransport()) : null;
121
127
  const zap = config.zap && nostr
122
128
  ? createZapBridge({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgesworn/moneyer",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "An LNURLcash (LUD-25) mint - strikes Lightning bearer notes. Independent implementation, cln/lnd funding sources, SQLite, zero HTTP framework.",
5
5
  "author": "TheCryptoDonkey",
6
6
  "license": "MIT",