spark.exposed

Lightning swaps

The reviewed Lightning-send path locks selected leaves before asking the configured SSP to pay the invoice

In the pinned JavaScript SDK's regular Lightning-send path, selected leaves are prepared for the configured SSP and locked at the Operator layer before the wallet asks that SSP to pay the invoice. The ordering engages protocol recovery if the hosted request fails; it does not show loss, misconduct, or absence of recourse. 12

2 sourcesEvidence reviewed through August 24, 2026

What the evidence shows

Technical and product details

  1. Documented behavior

    The pinned JavaScript SDK gives a regular Lightning send a 16-day expiry, selects leaves for the amount plus fee, and prepares their transfer to the configured SSP identity. 1

    Supporting material shown on this page

    Lightning-send orderingPinned source code · github.com · checked 2026-08-24
    Relevant lines from the pinned source · open raw file
    4802            );
    4803            this.leafManager.restoreLocalLockedToAvailable(untakenLeafIds);
    4804          }
    4805
    4806          const sspResponse = await sspClient.requestLightningSend({
    4807            encodedInvoice: invoice,
    4808            amountSats: isZeroAmountInvoice ? amountSatsToSend! : undefined,
  2. Documented behavior

    The wallet then calls the Operator-side preimage-swap flow. After a transfer is returned, the SDK advances local state and records that the leaves are locked at the Operator layer. 1

    Supporting material shown on this page

    Lightning-send orderingPinned source code · github.com · checked 2026-08-24
    Relevant lines from the pinned source · open raw file
    4802            );
    4803            this.leafManager.restoreLocalLockedToAvailable(untakenLeafIds);
    4804          }
    4805
    4806          const sspResponse = await sspClient.requestLightningSend({
    4807            encodedInvoice: invoice,
    4808            amountSats: isZeroAmountInvoice ? amountSatsToSend! : undefined,
  3. Documented behavior

    Only after that state transition does the SDK call requestLightningSend, passing the invoice and the outbound transfer ID to the configured SSP. 1

    Supporting material shown on this page

    Lightning-send orderingPinned source code · github.com · checked 2026-08-24
    Relevant lines from the pinned source · open raw file
    4802            );
    4803            this.leafManager.restoreLocalLockedToAvailable(untakenLeafIds);
    4804          }
    4805
    4806          const sspResponse = await sspClient.requestLightningSend({
    4807            encodedInvoice: invoice,
    4808            amountSats: isZeroAmountInvoice ? amountSatsToSend! : undefined,

Interpretation

Why this matters for Spark's trust model

Settlement and recovery are asymmetric in time: the Spark-side state transition precedes the hosted request that pays the Lightning invoice. A failed or unavailable SSP therefore engages the protocol's expiry and recovery mechanics rather than a simple client-side rollback. 12

This section states the trust-model consequence of the cited evidence. Conditional or inferred claims remain bounded by the next section.

Scope control

What this does not establish

  • This ordering is not evidence that the SSP can keep a user's value without recourse, that a payment failed, or that the flow is non-atomic. The reviewed protocol includes hash- and sequence-lock recovery branches, and integrators can configure another SSP. 12

Sources and excerpts

Primary sources

The relevant details and available source-code excerpts appear alongside the claims above. This list preserves the complete original-source trail for independent verification.

1

Lightning-send ordering

Pinned source code · github.com · Pinned or archival · checked 2026-08-24

Open original source
2

Lightning HTLC construction

Pinned source code · github.com · Pinned or archival · checked 2026-08-24

Open original source

How sources, absence findings, and limitations were evaluated