lnurlcash-kit 0.1.1 → 0.1.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 CHANGED
@@ -3,6 +3,26 @@
3
3
  Semantic versioning. While the LUD-25 draft is unmerged, `0.x` minor bumps
4
4
  may carry breaking changes; pin an exact version.
5
5
 
6
+ ## 0.1.2 - 2026-08-21
7
+
8
+ - `mintFeeBand` and `withinMintFeeBand`. LUD-25 states the mint fee as
9
+ `base_fee_msat` plus a ppm cut and says nothing about rounding, and the
10
+ two live implementations read that differently: dni's lnurl-mint - the
11
+ reference, and what every public mint on the awesome list except moneyer
12
+ runs - ceilings the fee to a whole sat on purpose so the mint is "never
13
+ short a sat", while moneyer withholds the msat-exact amount.
14
+ - So `applyMintFee` is right about exactly one of them, and a wallet
15
+ comparing a credited note against it warns spuriously against the other.
16
+ Measured on real sats: 40,000 msat at a 1000 + 1000 ppm mint credited
17
+ 38,000, not the 38,960 the formula gives.
18
+ - `mintFeeBand` returns the range - the formula is the most a holder can be
19
+ credited, the sat-ceilinged fee the least - and `withinMintFeeBand` is
20
+ what a caller should compare against. `applyMintFee` is unchanged and
21
+ still means the formula; it is now documented as the generous edge rather
22
+ than the answer.
23
+ - Nothing here decides which reading is correct. That is a question for
24
+ lnurl/luds#301.
25
+
6
26
  ## 0.1.1 - 2026-08-20
7
27
 
8
28
  - `fetchMintAddress` now populates `nodeCapacityMsat`. The wire field is
package/README.md CHANGED
@@ -178,6 +178,10 @@ The reference implementations, both dni's, both MIT:
178
178
  - [lnurl-mint](https://github.com/dni/lnurl-mint) — the reference service
179
179
  - [lnurl-wallet](https://github.com/dni/lnurl-wallet) — the reference wallet
180
180
 
181
+ Everything else built on LNURLcash — the other wallets and mints, the
182
+ hardware vault, the sibling language ports — is indexed in
183
+ [awesome-lnurlcash](https://github.com/TheCryptoDonkey/awesome-lnurlcash).
184
+
181
185
  Changes made on extraction are listed in [CHANGELOG.md](CHANGELOG.md); two
182
186
  are behavioural fixes worth reading if you are porting from that code.
183
187
 
package/dist/index.d.ts CHANGED
@@ -36,6 +36,12 @@ type MintFee = {
36
36
  };
37
37
  declare const parseMintFee: (metadata: string) => MintFee | null;
38
38
  declare const applyMintFee: (grossMsat: number, fee: MintFee) => number;
39
+ type MintFeeBand = {
40
+ minNetMsat: number;
41
+ maxNetMsat: number;
42
+ };
43
+ declare const mintFeeBand: (grossMsat: number, fee: MintFee) => MintFeeBand;
44
+ declare const withinMintFeeBand: (grossMsat: number, netMsat: number, fee: MintFee) => boolean;
39
45
  declare const grossUpForMintFee: (netMsat: number, fee: MintFee) => number;
40
46
  declare const formatFeePercent: (ppm: number) => string;
41
47
  declare const describeMintFee: (fee: MintFee) => string;
@@ -190,4 +196,4 @@ declare const createClient: (options?: LnurlcashOptions) => {
190
196
  };
191
197
  type LnurlcashClient = ReturnType<typeof createClient>;
192
198
 
193
- export { AmbiguousMintError, AmbiguousMutationError, type HashedMutationResult, type HashedSplitResult, type InvoiceResult, type LnurlcashClient, LnurlcashError, type LnurlcashOptions, type MeltResult, type MintAddressInfo, type MintFee, NoteSpentError, NoteUnknownError, type PayRequestInfo, PendingNoteError, ProtocolError, type RandomSecret, RequestRefusedError, type RotateResult, ServiceRejectedError, type SettledNote, type SplitResult, type VerifyResult, type WithdrawRequestInfo, type WithdrawSuccessResponse, applyMintFee, buildNoteUrl, classifyNoteError, createClient, decodeBolt11AmountMsat, defaultRandomSecret, describeMintFee, fetchInvoiceVerification, fetchMintAddress, fetchNoteInfo, fetchPayRequest, formatFeePercent, fromBech32Lnurl, fromLud17, grossUpForMintFee, hashK1, isAllowedServiceUrl, isBech32Lnurl, isBolt11Invoice, isLightningAddress, isPreimage, isValidNoteInput, lightningAddressUsername, meltNote, mergeNotes, mergeNotesWithHash, mintAddressUrl, noteDeclaredAmount, noteK1, noteSignature, noteSignatureDigest, noteSignatureMessage, parseMintFee, probeBurnedNote, requestInvoice, requireNoteK1, resolveLnurlInput, resolveMintInput, resolveNoteInput, rotateNote, rotateNoteWithHash, sameInvoice, serverOf, settleNote, splitNote, splitNoteWithHash, toBech32Lnurl, toLud17w, verifyNoteSignature, withNewK1, withoutK1 };
199
+ export { AmbiguousMintError, AmbiguousMutationError, type HashedMutationResult, type HashedSplitResult, type InvoiceResult, type LnurlcashClient, LnurlcashError, type LnurlcashOptions, type MeltResult, type MintAddressInfo, type MintFee, type MintFeeBand, NoteSpentError, NoteUnknownError, type PayRequestInfo, PendingNoteError, ProtocolError, type RandomSecret, RequestRefusedError, type RotateResult, ServiceRejectedError, type SettledNote, type SplitResult, type VerifyResult, type WithdrawRequestInfo, type WithdrawSuccessResponse, applyMintFee, buildNoteUrl, classifyNoteError, createClient, decodeBolt11AmountMsat, defaultRandomSecret, describeMintFee, fetchInvoiceVerification, fetchMintAddress, fetchNoteInfo, fetchPayRequest, formatFeePercent, fromBech32Lnurl, fromLud17, grossUpForMintFee, hashK1, isAllowedServiceUrl, isBech32Lnurl, isBolt11Invoice, isLightningAddress, isPreimage, isValidNoteInput, lightningAddressUsername, meltNote, mergeNotes, mergeNotesWithHash, mintAddressUrl, mintFeeBand, noteDeclaredAmount, noteK1, noteSignature, noteSignatureDigest, noteSignatureMessage, parseMintFee, probeBurnedNote, requestInvoice, requireNoteK1, resolveLnurlInput, resolveMintInput, resolveNoteInput, rotateNote, rotateNoteWithHash, sameInvoice, serverOf, settleNote, splitNote, splitNoteWithHash, toBech32Lnurl, toLud17w, verifyNoteSignature, withNewK1, withinMintFeeBand, withoutK1 };
package/dist/index.js CHANGED
@@ -253,6 +253,18 @@ var parseMintFee = (metadata) => {
253
253
  };
254
254
  var proportionalFee = (grossMsat, feePpm) => Math.floor(grossMsat / 1e6) * feePpm + Math.floor(grossMsat % 1e6 * feePpm / 1e6);
255
255
  var applyMintFee = (grossMsat, fee) => Math.max(0, grossMsat - fee.baseFeeMsat - proportionalFee(grossMsat, fee.feePpm));
256
+ var mintFeeBand = (grossMsat, fee) => {
257
+ const exactFee = fee.baseFeeMsat + proportionalFee(grossMsat, fee.feePpm);
258
+ const satCeilinged = Math.ceil(exactFee / 1e3) * 1e3;
259
+ return {
260
+ minNetMsat: Math.max(0, grossMsat - satCeilinged),
261
+ maxNetMsat: Math.max(0, grossMsat - exactFee)
262
+ };
263
+ };
264
+ var withinMintFeeBand = (grossMsat, netMsat, fee) => {
265
+ const { minNetMsat, maxNetMsat } = mintFeeBand(grossMsat, fee);
266
+ return netMsat >= minNetMsat && netMsat <= maxNetMsat;
267
+ };
256
268
  var grossUpForMintFee = (netMsat, fee) => {
257
269
  if (netMsat <= 0) return 0;
258
270
  let hi = netMsat + fee.baseFeeMsat;
@@ -711,4 +723,4 @@ var createClient = (options = {}) => ({
711
723
  fetchInvoiceVerification: (verifyUrl) => fetchInvoiceVerification(verifyUrl, options)
712
724
  });
713
725
 
714
- export { AmbiguousMintError, AmbiguousMutationError, LnurlcashError, NoteSpentError, NoteUnknownError, PendingNoteError, ProtocolError, RequestRefusedError, ServiceRejectedError, applyMintFee, buildNoteUrl, classifyNoteError, createClient, decodeBolt11AmountMsat, defaultRandomSecret, describeMintFee, fetchInvoiceVerification, fetchMintAddress, fetchNoteInfo, fetchPayRequest, formatFeePercent, fromBech32Lnurl, fromLud17, grossUpForMintFee, hashK1, isAllowedServiceUrl, isBech32Lnurl, isBolt11Invoice, isLightningAddress, isPreimage, isValidNoteInput, lightningAddressUsername, meltNote, mergeNotes, mergeNotesWithHash, mintAddressUrl, noteDeclaredAmount, noteK1, noteSignature, noteSignatureDigest, noteSignatureMessage, parseMintFee, probeBurnedNote, requestInvoice, requireNoteK1, resolveLnurlInput, resolveMintInput, resolveNoteInput, rotateNote, rotateNoteWithHash, sameInvoice, serverOf, settleNote, splitNote, splitNoteWithHash, toBech32Lnurl, toLud17w, verifyNoteSignature, withNewK1, withoutK1 };
726
+ export { AmbiguousMintError, AmbiguousMutationError, LnurlcashError, NoteSpentError, NoteUnknownError, PendingNoteError, ProtocolError, RequestRefusedError, ServiceRejectedError, applyMintFee, buildNoteUrl, classifyNoteError, createClient, decodeBolt11AmountMsat, defaultRandomSecret, describeMintFee, fetchInvoiceVerification, fetchMintAddress, fetchNoteInfo, fetchPayRequest, formatFeePercent, fromBech32Lnurl, fromLud17, grossUpForMintFee, hashK1, isAllowedServiceUrl, isBech32Lnurl, isBolt11Invoice, isLightningAddress, isPreimage, isValidNoteInput, lightningAddressUsername, meltNote, mergeNotes, mergeNotesWithHash, mintAddressUrl, mintFeeBand, noteDeclaredAmount, noteK1, noteSignature, noteSignatureDigest, noteSignatureMessage, parseMintFee, probeBurnedNote, requestInvoice, requireNoteK1, resolveLnurlInput, resolveMintInput, resolveNoteInput, rotateNote, rotateNoteWithHash, sameInvoice, serverOf, settleNote, splitNote, splitNoteWithHash, toBech32Lnurl, toLud17w, verifyNoteSignature, withNewK1, withinMintFeeBand, withoutK1 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lnurlcash-kit",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "LNURLcash (LUD-25) bearer note client for TypeScript - mint, rotate, split, merge, melt, and verify offline",
5
5
  "author": "TheCryptoDonkey",
6
6
  "license": "MIT",
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "^26.2.0",
63
- "lnurlcash-conformance": "^0.1.0",
63
+ "lnurlcash-conformance": "^0.1.1",
64
64
  "tsup": "^8.5.0",
65
65
  "typescript": "^5.7.0",
66
66
  "vitest": "^3.0.0"