Class LightningReceiveGates
- Namespace
- NArk.ArkadeIntents.Lightning
- Assembly
- NArk.ArkadeIntents.dll
The receive client's checks on what the solver sent back: pure decisions over a quote.
public static class LightningReceiveGates
- Inheritance
-
LightningReceiveGates
- Inherited Members
Remarks
Kept free of I/O so each check is testable at its exact boundary, the same way LightningSendGates is on the send leg.
Fields
MinClaimWindowSeconds
The minimum time the claim window must stay open after the payer's deadline, in seconds.
public const long MinClaimWindowSeconds = 1800
Field Value
Remarks
Once the solver's reclaim opens the claim refuses to race it, so the window between "the
payer can still pay" and "the solver can take its lockup back" is the whole opportunity to
take delivery. Sized to the reference client's MIN_CLAIM_WINDOW_SECONDS.
Methods
AssertReceivable(RfqQuote<LightningReceiveQuoteProfile>, BOLT11PaymentRequest, long, long?)
public static long AssertReceivable(RfqQuote<LightningReceiveQuoteProfile> quote, BOLT11PaymentRequest invoice, long now, long? maxPayAmountSats = null)
Parameters
quoteRfqQuote<LightningReceiveQuoteProfile>invoiceBOLT11PaymentRequestnowlongmaxPayAmountSatslong?
Returns
ResolveLockupContract(RfqQuote<LightningReceiveQuoteProfile>, VHTLCv2Contract, VHTLCv2Contract, bool)
Pick which of the client's two derived lockup shapes the solver will actually fund; refuse if neither matches, including when the solver sends no address at all.
public static VHTLCv2Contract ResolveLockupContract(RfqQuote<LightningReceiveQuoteProfile> quote, VHTLCv2Contract eightLeaf, VHTLCv2Contract nineLeaf, bool isMainnet)
Parameters
quoteRfqQuote<LightningReceiveQuoteProfile>The quote carrying the compare-only address.
eightLeafVHTLCv2ContractThe candidate without the timelocked refund leaf.
nineLeafVHTLCv2ContractThe candidate with it.
isMainnetboolWhich network's address encoding to compare under.
Returns
- VHTLCv2Contract
Whichever candidate matched.
Remarks
The solver funds this corridor's lockup, so getting the shape right here is not merely a funding gate the way it is on the send leg — a wrong guess would leave the client watching an address the solver never pays, and the swap would simply never be seen as funded. Comparing against both shapes, rather than one guessed one, is what makes this tolerant of a solver either side of the timelocked refund leaf.
lockup_address is a REQUIRED field of the RFQ protocol's receive quote (the spec marks
optional fields explicitly elsewhere — payment_evidence, claim_packet — this one
is not among them). A solver that omits it is already out of spec, and defaulting to a guessed
shape would mean trusting exactly the solver that broke the one contract this check exists to
hold it to. This corridor used to default to its single derived shape here, which was correct
while only one shape existed; now that a second does, an absent address is refused the same
way Send and Onchain already refuse it. That is a deliberate tightening of a pre-existing
lenient path, not a bug fix — anything relying on the old leniency was already out of spec.
Exceptions
- LockupAddressMismatchException
The quoted address matches neither candidate.
VerifyInvoice(RfqQuote<LightningReceiveQuoteProfile>, string, long, RfqAmountSide, Network)
Check the solver's invoice against what was actually asked for, and return it decoded.
public static BOLT11PaymentRequest VerifyInvoice(RfqQuote<LightningReceiveQuoteProfile> quote, string expectedPaymentHash, long requestedSats, RfqAmountSide amountSide, Network network)
Parameters
quoteRfqQuote<LightningReceiveQuoteProfile>The solver's quote.
expectedPaymentHashstringThe hash the client requested against, hex.
requestedSatslongThe size the client asked for, on the leg
amountSidenames.amountSideRfqAmountSideWhich leg the client pinned when it asked.
networkNetworkThe network to decode on.
Returns
- BOLT11PaymentRequest
The decoded invoice.
Remarks
The invoice is the one thing here a third party acts on, so it is checked rather than trusted. A wrong payment hash would be an invoice the client's own preimage can never settle — the payer's money would move and the swap still could not complete.
The two amounts are checked against different things, and mixing them up is easy: on this
corridor from_amount is what the PAYER owes, so it is what the invoice must say, while
to_amount is what lands on Arkade. They differ by the solver's fee, so comparing the
invoice against the payout would refuse every quote that charges anything — and comparing the
payout against nothing would accept a quote that quietly delivers less than was asked for.
Which of the two the request pinned decides which one is checked against it, and checking the wrong one refuses every honest quote. An exact-out request fixes the payout and lets the charge float up by the fee; an exact-in request fixes the charge and lets the payout float down by it. Holding a quote to the leg the client did not pin would be holding it to a number nobody agreed on.
Exceptions
- LightningReceiveNotUsableException
The invoice is missing, wrong or unusable.