@forgesworn/moneyer 0.3.0 → 0.3.2
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 +34 -0
- package/dist/server.js +18 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.2] - 2026-08-22
|
|
4
|
+
|
|
5
|
+
- **A note with a melt in flight is no longer advertised as withdrawable.**
|
|
6
|
+
The mutating callback already refused a pending note; the informational
|
|
7
|
+
GET did not, so the check LUD-25 points a careful holder at was the one
|
|
8
|
+
that lied. That is the exact gap a sell-during-melt needs: start a melt,
|
|
9
|
+
show the buyer a healthy GET, take payment out of band, let the melt
|
|
10
|
+
settle. `fetchNoteInfo` on a pending note now fails the same way the
|
|
11
|
+
callback does, and lnurlcash-kit classifies it as `PendingNoteError`, so
|
|
12
|
+
a wallet parks the note rather than writing it off as unknown. Found by
|
|
13
|
+
re-reading LUD-25 against dni's lnurl-mint, which has had this guard.
|
|
14
|
+
- A flake in the melt suite: `leaves an unconfirmable outcome pending`
|
|
15
|
+
slept a fixed 100 ms, which was waiting for an in-flight melt to finish
|
|
16
|
+
exhausting its confirmations rather than for any state, and reconcile
|
|
17
|
+
deliberately skips a melt this process still has in flight. It now
|
|
18
|
+
retries reconcile until it can act.
|
|
19
|
+
|
|
20
|
+
## [0.3.1] - 2026-08-22
|
|
21
|
+
|
|
22
|
+
- **Rounding the fee to a whole sat now really is the default.** 0.3.0
|
|
23
|
+
documented `roundFeeToSat` as on unless turned off, and made it so for a
|
|
24
|
+
mint started from the CLI, where the environment reader fills the
|
|
25
|
+
default in. A mint built by calling `createMoneyer` with a config object
|
|
26
|
+
passes the field through as absent, and the server read absent as off -
|
|
27
|
+
so an embedder got a mint that kept fractions of a sat while the same
|
|
28
|
+
mint from the binary rounded them away. Absent now means on in both,
|
|
29
|
+
and only an explicit `false` opts out.
|
|
30
|
+
|
|
31
|
+
It hid because every test that cared about rounding set the flag
|
|
32
|
+
explicitly, so nothing exercised the default through the library at all.
|
|
33
|
+
Found from the other side: notecase's cross-implementation suite began
|
|
34
|
+
asserting what a wallet is actually credited, and the mint it builds in
|
|
35
|
+
process disagreed with the mint on the wire.
|
|
36
|
+
|
|
3
37
|
## [0.3.0] - 2026-08-22
|
|
4
38
|
|
|
5
39
|
- **The mint fee is now ceilinged to a whole sat by default.**
|
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
|
-
|
|
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
|
|
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({
|
|
@@ -670,6 +676,16 @@ export const createMoneyer = async (config, deps = {}) => {
|
|
|
670
676
|
return fail('Unknown note.');
|
|
671
677
|
if (note.state === 'burned')
|
|
672
678
|
return fail('Note already spent.');
|
|
679
|
+
// A note reserved by an in-flight melt is not withdrawable, and must
|
|
680
|
+
// not be advertised as though it were. LUD-25 makes this GET the way
|
|
681
|
+
// anyone checks what a note is worth, so answering "live, worth all
|
|
682
|
+
// of it" about a note halfway out of the door is the exact lie a
|
|
683
|
+
// sell-during-melt needs: the seller starts a melt, shows the buyer a
|
|
684
|
+
// healthy GET, takes payment out of band, and the melt settles. Same
|
|
685
|
+
// reason the mutating callback already gives, and the same one dni's
|
|
686
|
+
// lnurl-mint gives here.
|
|
687
|
+
if (note.state === 'pending')
|
|
688
|
+
return fail('pending');
|
|
673
689
|
// maxWithdrawable states the note's value, as the reference does.
|
|
674
690
|
// minWithdrawable is that value floored to a whole sat: most Lightning
|
|
675
691
|
// wallets can only invoice whole sats, and a note of 94.9 sat that
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgesworn/moneyer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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",
|