Skip to content

assets: Add shared asset tooling - #1225

Open
hieblmi wants to merge 5 commits into
lightninglabs:masterfrom
hieblmi:codex/shared-asset-swapkit
Open

assets: Add shared asset tooling#1225
hieblmi wants to merge 5 commits into
lightninglabs:masterfrom
hieblmi:codex/shared-asset-swapkit

Conversation

@hieblmi

@hieblmi hieblmi commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • make Loop the single home for the shared asset HTLC scripts, immutable
    SwapKit, legacy deposit kit, and generic OP_TRUE virtual-packet sweep
    helper
  • preserve the existing deposit contract as the explicit
    LegacyDepositV0 policy, pinned by golden script, key, anchor, witness, and
    virtual-packet vectors
  • expose narrow boundaries that both the client and server can import
  • use Taproot Assets v0.8.3, taprpc v1.3.3, and LND v0.21.3-beta,
    with Go 1.25.13 and classic btcd; this prototype does not add tap-sdk

Security and correctness boundaries

The shared kit verifies proofs before using them and binds every Bitcoin
spend to the proof's exact anchor outpoint, output value, script, commitment
root, and unique PSBT input. It supplies every prevout to the signer, applies
the required CSV sequence to the matched input without mutating the caller's
PSBT on failure, rejects malformed signer responses, verifies the returned
Schnorr signature, and returns the matched input index to the caller.

The OP_TRUE helper rejects empty, nil, invalid, non-OP_TRUE, mixed-asset,
overflowing, and amount-mismatched proof sets. It derives the network from the
destination address and validates the prepared output and split-root witness
before attaching the asset witness.

Network validation distinguishes shared testnet HRPs by Bitcoin network
magic. Simnet explicitly accepts both btcd's native BIP-0044 coin type 115 and
lnd's testnet-compatible coin type 1 without relying on mutable global state.

Feature state machines remain responsible for trusted proof import,
canonical-chain and confirmation tracking, reorg handling, destination
validation, quote and fee limits, and durable recovery. This PR adds no Asset
Loop Out RPC, funding flow, persistence, or state machine, and does not alter
conventional Loop In or Asset Loop In.

This is prototype infrastructure, not a release or rollout change.

Verification

  • GOTOOLCHAIN=go1.25.13 go test ./... -count=1 -timeout=10m
  • GOTOOLCHAIN=go1.25.13 go test -race ./assets/... -count=1
  • GOTOOLCHAIN=go1.25.13 go vet ./assets/...
  • GOTOOLCHAIN=go1.25.13 CGO_ENABLED=0 go build -tags=dev ./cmd/loop ./cmd/loopd
  • GOTOOLCHAIN=go1.25.13 go mod verify in the root and looprpc modules
  • GOTOOLCHAIN=go1.25.13 go mod tidy -diff in the root, looprpc, and
    swapserverrpc modules
  • GOTOOLCHAIN=go1.25.13 go test ./... -count=1 in the looprpc and
    swapserverrpc modules
  • make commitmsg-lint range=origin/master..HEAD
  • git diff --check origin/master..HEAD

@hieblmi hieblmi added the no-changelog Skip the release notes CI check label Sep 2, 2026
@hieblmi
hieblmi force-pushed the codex/shared-asset-swapkit branch 4 times, most recently from c206f0d to 2814bf6 Compare September 3, 2026 05:54
@hieblmi hieblmi added asset loop out Taproot Asset Loop Out work and removed no-changelog Skip the release notes CI check labels Sep 3, 2026
@hieblmi hieblmi changed the title assets: Add shared asset HTLC kit assets: Add shared asset tooling Sep 3, 2026
@hieblmi hieblmi added the no-changelog Skip the release notes CI check label Sep 3, 2026
@hieblmi
hieblmi force-pushed the codex/shared-asset-swapkit branch 2 times, most recently from 4283082 to 50595de Compare September 3, 2026 08:12
@hieblmi hieblmi self-assigned this Sep 3, 2026
@hieblmi
hieblmi marked this pull request as ready for review September 3, 2026 12:22
@hieblmi

hieblmi commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

/gateway review

@lightninglabs-gateway

Copy link
Copy Markdown

👀 gateway review starting…

@starius starius left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style — ~18 unexported funcs and ~14 test helpers have no godoc, against the convention. Non-test: canonicalAddressParams, cloneAddressParams (both copies), validateScripts, genBtcControlBlock, validateAsset (both), findUniqueInput (both), validateSweep (both), validateSequence, verifyTapscriptSignature (both), timeoutPathSibling, encodedTimeoutPathSibling, newHtlcSwapKit, validateProof.

Comment thread assets/tapkit.go Outdated
Comment thread assets/tapkit.go
Comment thread assets/deposit/kit.go
Comment thread assets/deposit/kit.go
Comment thread assets/deposit/kit.go Outdated
Comment thread assets/deposit/kit.go
Comment thread assets/htlc/swapkit.go
@hieblmi

hieblmi commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up commit 818876e also adds documentation to the unexported production and test helpers listed in the general review. Local verification passed: go test ./..., go test -race ./assets/..., go vet ./..., golangci-lint (0 issues), plus a Nautilus #1712 itest-package compile with integration tags.

@hieblmi
hieblmi requested a review from starius September 8, 2026 13:05
Move the existing server asset HTLC contract into Loop so both
sides can derive and spend the same commitment. Freeze the legacy
vectors and bind witness construction to verified proofs, prevouts,
and input indices.

Reserve future policies so Loop Asset Out can choose its contract
explicitly instead of inheriting the deposit key path.
Consolidate the remaining deposit and OP_TRUE virtual-packet helpers
behind Loop-owned packages. Replace positional sweep assumptions with
proof-bound input selection, complete prevout validation, and explicit
signature verification.
Reject non-block deposit expiries. This prevents BIP68 flags from
changing or disabling the intended block delay.

Canonicalize OP_TRUE keys, populate and validate every virtual input
witness, and reject unsupported addresses and duplicate anchor inputs.
Return the complete anchor Merkle root from proof verification.

This lets MuSig2 spends reproduce the output's Taproot tweak.
Align taprpc and LND with the Taproot Assets v0.8.3 dependency graph.
Raise the minimum Go build version to 1.25.13 and refresh module sums
for both the main and client RPC modules.
@hieblmi
hieblmi force-pushed the codex/shared-asset-swapkit branch from 818876e to 81e876c Compare September 8, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset loop out Taproot Asset Loop Out work no-changelog Skip the release notes CI check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants