mirror of
https://github.com/tompro/sattle.git
synced 2026-10-26 01:49:58 +00:00
fix(lnurlcash): assert named claims land at the wallet's own secret
Review feedback: bind the claim answer to the secret that was polled before building a note from it. The kit already guarantees this - claimMintedNote returns the queried secret by construction and fetchNoteInfo rejects a mismatched k1 echo - so the assert cannot trip through the kit (and is therefore not separately testable); it exists so a future kit regression fails loudly instead of tracking a wrong secret.
This commit is contained in:
@@ -245,6 +245,13 @@ export const claimFromSecret = async (
|
|||||||
// is lying about the note it just credited
|
// is lying about the note it just credited
|
||||||
throw new Error('The mint reports the freshly minted note as already spent.')
|
throw new Error('The mint reports the freshly minted note as already spent.')
|
||||||
}
|
}
|
||||||
|
if (claim.k1 !== target.noteSecret) {
|
||||||
|
// belt and suspenders: the kit's claimMintedNote returns the queried
|
||||||
|
// secret by construction and fetchNoteInfo rejects a mismatched echo,
|
||||||
|
// so this cannot trip through the kit - if it ever does, building a
|
||||||
|
// note from the answer would track the wrong secret
|
||||||
|
throw new Error('The mint answered the claim for a different note secret.')
|
||||||
|
}
|
||||||
if (claim.amountMsat === null || !claim.callback) {
|
if (claim.amountMsat === null || !claim.callback) {
|
||||||
throw new Error('The mint did not return the minted note details.')
|
throw new Error('The mint did not return the minted note details.')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,10 +215,18 @@ export const transferBetweenMints = async (
|
|||||||
// proof - the target only credits it once the melt's payment landed
|
// proof - the target only credits it once the melt's payment landed
|
||||||
try {
|
try {
|
||||||
const claim = await pollMintClaim(prepared.withdrawLink, noteSecret, poll, options)
|
const claim = await pollMintClaim(prepared.withdrawLink, noteSecret, poll, options)
|
||||||
if (claim.state !== 'minted' || claim.amountMsat === null || !claim.callback) {
|
if (
|
||||||
// 'spent' on a fresh wallet-chosen secret, or an incomplete
|
claim.state !== 'minted' ||
|
||||||
// answer: the target misbehaved - the way back to the note is
|
claim.k1 !== noteSecret ||
|
||||||
// already in the claim material
|
claim.amountMsat === null ||
|
||||||
|
!claim.callback
|
||||||
|
) {
|
||||||
|
// 'spent' on a fresh wallet-chosen secret, a claim naming a
|
||||||
|
// secret other than the one polled (impossible through the kit,
|
||||||
|
// which returns the queried secret and rejects mismatched
|
||||||
|
// echoes - asserted anyway: building from it would track the
|
||||||
|
// wrong note), or an incomplete answer: the target misbehaved -
|
||||||
|
// the way back to the note is already in the claim material
|
||||||
return {...base, outcome: 'settled-claim-failed', claimMaterial}
|
return {...base, outcome: 'settled-claim-failed', claimMaterial}
|
||||||
}
|
}
|
||||||
const note: NewBearer = {
|
const note: NewBearer = {
|
||||||
|
|||||||
Reference in New Issue
Block a user