Skip to content

swap: an asset↔asset offer cannot be requested or filled — one program and one TLV field short #768

Description

@pietro909

@arkade-os/swap can neither request nor fill an offer where both legs name an
asset. The solver decides such offers as of
lightning-swap-service#110
(merged), so the two sides now disagree about what the corridor serves.

Nothing is broken in production: no orchestrator serves an asset leg yet
(lss#125 tracks
what each leg still needs), and every failure below is loud. Filing it now because
closing it is design work, not a patch, and the solver side has already landed.

What the solver admits

src/core/assetOffer.ts models both sides as string | nullwantAssetId and
offerAssetId — with null meaning BTC, and its markets are unordered pairs of
asset ids with null
. Both non-null is a served market; only the same asset on
both sides is refused, as degenerate_pair. On the wire, lss#113 makes the pair
arkade:<68-hex>->arkade:<68-hex> (152 chars, inside the 158 cap it sized for
exactly this case).

Where this SDK stops it

Four places, at origin/master:

site what it enforces
packages/swap/src/offer.ts:40-41,54-55,91 two covenant programs only — swap-want-asset.program.json / swap-want-btc.program.json, selected by offer.wantAsset ? … : …
offer.ts:138,189 the offer TLV carries ONE asset field (wantAsset, tag 0x03), not two
offer.ts:165 and offer.ts:238 "offer must carry exactly one of wantAsset or offerAsset", on build and on TLV decode
rfq.ts:259-265 (arkadeSwapRequest), rfq.ts:971 (offerTermsFromQuote) the same invariant at the request and quote-mapping layers

The failure is loud and early — arkadeSwapRequest throws before anything reaches
a solver, so a client cannot even ask. That is the right behaviour for today; it
is not a bug to fix in isolation.

What closing it needs

  1. A third covenant program: deliver asset X against a deposit of asset Y. The
    existing two are "the fill must deliver an asset" and "the fill must deliver
    sats"; neither constrains both legs.
  2. A widened offer TLV that can name two assets and say which is which, plus
    the decode-side rule that replaces "exactly one".
  3. Relaxing the four guards above, in that order — they are correct until 1 and 2
    exist, and relaxing them first would let a caller build a request the fill path
    cannot settle.

Worth designing against lss#107's covenant and this repo's #763 together, rather
than after either merges.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions