Skip to content

oor+vtxo: activate VTXO actors for OOR receives, add ChainDepth plumbing - #173

Merged
Roasbeef merged 10 commits into
mainfrom
fix/oor-vtxo-manager-notify
Mar 13, 2026
Merged

oor+vtxo: activate VTXO actors for OOR receives, add ChainDepth plumbing#173
Roasbeef merged 10 commits into
mainfrom
fix/oor-vtxo-manager-notify

Conversation

@ellemouton

@ellemouton ellemouton commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

Partial progress on #124 (Parts 1 and 2)

Summary

This PR addresses the OOR receive lifecycle gap from #124 and lays the
data-model groundwork for chain-depth-aware exit policy.

It does two things:

  1. It fixes OOR receive so incoming VTXOs do not stop at "persisted row in
    the DB". After an incoming OOR VTXO is materialized, the OOR flow now
    notifies VTXOManager, which spawns a live VTXO actor for that
    descriptor.
  2. It adds first-class ChainDepth tracking to VTXOs. ChainDepth is
    distinct from TreeDepth: it represents the number of OOR checkpoint
    hops between a VTXO and the most recent on-chain commitment.

What This PR Covers

Part 1: OOR receive now activates VTXO actors

Before this change, incoming OOR VTXOs were written to the vtxos table but
never forwarded to VTXOManager, so no VTXO actor was spawned.

This PR changes that by:

  • wiring the OOR actor to a real VTXOManager
  • notifying the manager after incoming OOR VTXOs are durably materialized
  • having the manager spawn actors for already-persisted descriptors
  • wiring daemon startup so both round-created and OOR-created VTXOs flow into
    the same manager

Result:

  • OOR-received VTXOs now participate in the normal actor lifecycle
  • expiry monitoring, forfeit handling, and related VTXO-actor-driven behavior
    are no longer bypassed for received OOR VTXOs

Part 2: persisted ChainDepth plumbing

This PR also introduces ChainDepth on VTXOs and threads it through:

  • vtxo.Descriptor
  • OOR incoming metadata / descriptor construction
  • DB schema and persistence
  • daemon RPC VTXO responses
  • indexer VTXO protobufs
  • tests and systest coverage

Round-created VTXOs explicitly default to ChainDepth = 0.

What This PR Does Not Cover

This PR does not complete the full production metadata wiring needed to
source authoritative non-zero incoming OOR ChainDepth.

That gap already existed before this branch:

  • the live OOR actor setup in darepod/server.go still does not wire the full
    incoming metadata resolver path
  • because of that, the live daemon still lacks the production source that
    should eventually provide incoming OOR lineage metadata, including chain
    depth

So while this PR makes the model, storage, and APIs ready for
chain-depth-aware behavior, it does not claim to fully complete Part 2
end-to-end in production.

This PR also does not implement Part 3 from #124:

  • no fee-based unilateral-exit cost model
  • no chain-depth-aware go-on-chain policy changes
  • no change to the expiry policy beyond making the correct field available for
    future work

Why This Split Still Makes Sense

Even without the final production metadata resolver wiring, this PR is still
valuable on its own because it:

  • fixes the original actor-lifecycle bug for OOR receives
  • eliminates the need for a future schema migration or proto break when
    chain-depth-aware policy lands
  • keeps the code honest by preserving ChainDepth wherever authoritative
    metadata is supplied, without inventing values from TreeDepth

Testing

Covered by:

  • unit tests for OOR manager notification wiring
  • unit tests for round manager wiring
  • unit tests for ChainDepth propagation and round-trip persistence
  • systest proving OOR materialization results in a live VTXO actor, and that
    injected ChainDepth survives materialization/persistence

Commands run:

  • make unit pkg=oor, make unit pkg=vtxo, make unit pkg=db, make unit pkg=darepod
  • go test -tags systest ./systest -run TestOORIncomingMaterializationSpawnsVTXOActor -count=1
  • make lint

Follow-up Work

Remaining follow-up after this PR:

  • wire the production OOR incoming metadata resolver path in
    darepod/server.go
  • source authoritative incoming OOR ChainDepth from the receive metadata
    path
  • implement Part 3 policy logic using ChainDepth instead of overloading
    TreeDepth

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the handling of Virtual Transaction Outputs (VTXOs) by resolving a critical gap in the Out-of-Round (OOR) receive process. Previously, OOR-received VTXOs were persisted but not fully integrated into the system's active management, leading to bypassed lifecycle events. This change ensures that all VTXOs, regardless of their origin, are properly monitored and managed. Additionally, it introduces a robust mechanism for tracking ChainDepth, providing a more granular and accurate understanding of a VTXO's lineage and its proximity to an on-chain commitment, which is foundational for future policy implementations.

Highlights

  • OOR VTXO Actor Activation: Incoming Out-of-Round (OOR) VTXOs are now properly activated by the VTXOManager after persistence, ensuring they participate in the full actor lifecycle, including expiry monitoring and forfeit handling.
  • ChainDepth Tracking: A new ChainDepth field has been introduced to VTXOs, representing the number of OOR checkpoint hops from the VTXO to the most recent on-chain commitment. Round-created VTXOs are explicitly assigned a ChainDepth of 0. This new field is plumbed through various components including vtxo.Descriptor, OOR incoming metadata, database schema, daemon RPC responses, and indexer protobufs.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • arkrpc/indexer.pb.go
    • Added the ChainDepth field and its corresponding getter method to the VTXO protobuf message.
  • arkrpc/indexer.proto
    • Defined the new chain_depth field (uint32, field 15) within the VTXO protobuf message.
  • daemonrpc/daemon.pb.go
    • Included the ChainDepth field and its getter method in the VTXO protobuf message for daemon RPC.
  • daemonrpc/daemon.proto
    • Added the chain_depth field (uint32, field 10) to the VTXO protobuf message for daemon RPC.
  • darepod/rpc_server.go
    • Mapped the ChainDepth from the internal vtxo.Descriptor to the daemonrpc.VTXO protobuf message for RPC responses.
  • darepod/server.go
    • Imported the vtxo package.
    • Updated actor initialization logic to integrate the VTXO manager, allowing the round actor to notify it of new VTXOs and the OOR actor to notify it of materialized VTXOs.
    • Added a new mapRoundVTXOManagerMsg function to adapt round-owned manager notifications.
  • db/actordelivery/sqlc/models.go
    • Added a ChainDepth field of type int32 to the Vtxo database model.
  • db/migrations.go
    • Incremented the LatestMigrationVersion to 5 to reflect the new database schema change.
  • db/round_store.go
    • Initialized the ChainDepth field to 0 when converting a domain VTXO to database insert parameters.
  • db/sqlc/migrations/000005_vtxo_chain_depth.down.sql
    • Created a new migration script to drop the chain_depth column from the vtxos table.
  • db/sqlc/migrations/000005_vtxo_chain_depth.up.sql
    • Created a new migration script to add the chain_depth column (INTEGER NOT NULL DEFAULT 0) to the vtxos table.
  • db/sqlc/models.go
    • Added a ChainDepth field of type int32 to the Vtxo database model.
  • db/sqlc/queries/round.sql
    • Modified the InsertVTXO query to include chain_depth in both the INSERT and ON CONFLICT DO UPDATE clauses.
  • db/sqlc/round.sql.go
    • Updated SQL queries (GetVTXO, InsertVTXO, ListAllVTXOs, ListUnspentVTXOs, ListVTXOsByRound) and the InsertVTXOParams struct to support the new chain_depth column.
  • db/sqlc/schemas/generated_schema.sql
    • Updated the vtxos table schema to include the chain_depth column with a default value of 0.
  • db/sqlc/vtxo.sql.go
    • Modified ListLiveVTXOs and ListVTXOsByStatus queries to select the new chain_depth column.
  • db/vtxo_store.go
    • Implemented mapping for ChainDepth when converting between vtxo.Descriptor and database Vtxo models for persistence.
  • db/vtxo_store_test.go
    • Added TestVTXOPersistenceStoreChainDepthRoundTrip to confirm that ChainDepth values are correctly saved and retrieved from the database.
  • oor/actor.go
    • Imported the vtxo package.
    • Integrated the VTXOManager into the OOR client actor configuration and added logic to wire the local persistence handler to notify the VTXO manager of materialized VTXOs.
  • oor/actor_test.go
    • Imported the vtxo package.
    • Added new tests to verify that the OOR client actor correctly wires and uses the VTXO manager for notifications of incoming VTXOs.
  • oor/incoming_vtxo.go
    • Added ChainDepth to IncomingVTXOMetadata and ensured it is propagated when building an incoming VTXO descriptor.
  • oor/incoming_vtxo_test.go
    • Added tests to confirm that ChainDepth is correctly propagated from incoming metadata to the VTXO descriptor, including explicit zero values.
  • round/actor.go
    • Updated the RoundClientConfig to use a specific VTXOManagerMsg type and added a SetVTXOManager method for runtime wiring.
  • round/actor_harness_test.go
    • Modified the mockVTXOManagerRef to align with the new VTXOManagerMsg interface.
  • round/actor_test.go
    • Added a test case to ensure the VTXO manager can be wired late and still receive VTXO creation notifications.
  • systest/oor_vtxo_manager_test.go
    • Added a new system test to validate the end-to-end flow of OOR incoming VTXO materialization, including VTXO manager notification and actor spawning.
  • vtxo/interfaces.go
    • Added the ChainDepth field to the Descriptor struct, along with a detailed explanation of its purpose and distinction from TreeDepth.
  • vtxo/manager.go
    • Implemented handleVTXOsMaterialized to spawn VTXO actors for pre-persisted VTXOs and ensured ChainDepth is set to 0 for VTXOs created directly from a round.
  • vtxo/manager_test.go
    • Added TestClientVTXOToDescriptorChainDepthZero to verify that round-created VTXOs correctly have a ChainDepth of 0.
  • vtxo/messages.go
    • Introduced VTXOsMaterializedResp and VTXOsMaterializedNotification messages to facilitate communication with the VTXO manager regarding materialized VTXOs.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This PR is well-structured and effectively addresses the OOR receive lifecycle gap. The introduction of ChainDepth is a good step for future policy decisions, and the code is clear. The addition of extensive tests, including a system test, is commendable. I found one potential data race issue in the new SetVTXOManager method, which I've commented on. Otherwise, the changes look solid.

Comment thread round/actor.go Outdated
Comment on lines +349 to +351
func (a *RoundClientActor) SetVTXOManager(ref actor.TellOnlyRef[VTXOManagerMsg]) {
a.cfg.VTXOManager = ref
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This function modifies a.cfg.VTXOManager on a potentially running actor, but there's no synchronization to prevent data races. The RoundClientActor is started within initRoundActor before this method is called in darepod/server.go. If the actor's message loop reads a.cfg.VTXOManager at the same time this function writes to it, a data race will occur.

To fix this, you should use a mutex to protect access to a.cfg.VTXOManager. Assuming RoundClientActor has a mutex (e.g., a.mu), you should lock it in this function and also around any reads of this field. For example:

func (a *RoundClientActor) SetVTXOManager(ref actor.TellOnlyRef[VTXOManagerMsg]) {
	a.mu.Lock()
	defer a.mu.Unlock()
	a.cfg.VTXOManager = ref
}

Remember to also protect the reads in the actor's message loop.

Comment thread oor/actor.go Outdated
Comment on lines +149 to +151
func NewOORClientActor(cfg ClientActorCfg) *OORClientActor {
wireVTXOManagerNotifier(&cfg)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixing

@ellemouton
ellemouton force-pushed the fix/oor-vtxo-manager-notify branch 4 times, most recently from 35f546f to f91f08e Compare March 12, 2026 08:08
@ellemouton

Copy link
Copy Markdown
Contributor Author

@claude review this

@claude

claude Bot commented Mar 12, 2026

Copy link
Copy Markdown

Claude finished @ellemouton's task in 3m 35s —— View job


Code Review

  • Gather context and read changed files
  • Review OOR actor changes (oor/actor.go, oor/incoming_vtxo.go, oor/local_persistence_handler.go)
  • Review VTXO manager changes (vtxo/manager.go, vtxo/messages.go, vtxo/interfaces.go)
  • Review round actor changes (round/actor.go)
  • Review DB/schema changes (db/vtxo_store.go, db/round_store.go, migrations)
  • Review server wiring (darepod/server.go)
  • Review test coverage
  • Compile final review feedback

Overall this is a well-structured PR. The OOR → VTXO actor lifecycle fix is clean, the ChainDepth plumbing is consistent end-to-end, and the test coverage (unit + systest) is solid. A few issues and nits below.

Confirmed Issue: Data Race in SetVTXOManager (echoing Gemini's flag)

round/actor.go:349-351 — Gemini's flag is correct. The RoundClientActor is fully started inside initRoundActor (goroutine running) before startWalletDependentActors calls SetVTXOManager. The actor's dispatch loop reads a.cfg.VTXOManager on every VTXOCreatedNotification, while the main goroutine writes it — with no synchronization between them.

The cleanest fix is to remove SetVTXOManager entirely and pass VTXOManager as part of RoundClientActorCfg before calling Start. The current two-step pattern exists to break the circular dependency (vtxo manager ref is only available after initVTXOManager), but that dependency chain is already resolved before initRoundActor is called — the vtxo manager just doesn't exist yet because initVTXOManager is called after initRoundActor. Reordering so initVTXOManager runs first would let you pass the ref directly in the config:

// In startWalletDependentActors:
vtxoManagerRef, err := s.initVTXOManager(ctx, chainSourceRef)
...
roundActor, err := s.initRoundActor(ctx, chainSourceRef, walletRef, timeoutRef, vtxoManagerRef)

If reordering isn't desirable, the alternative is an atomic.Value or a mutex around the field. Fix this →

initOORActor: Incoming VTXOs still can't be materialized in production

darepod/server.go:1649-1653LocalPersistenceOutboxHandler is constructed without OperatorKey, ExitDelay, ResolveIncomingClientKey, or ResolveIncomingMetadata. If the daemon receives an incoming OOR transfer, handleMaterializeIncoming will immediately return "operator key must be provided" before any VTXOs are persisted.

The PR description acknowledges this gap, but there's no guard/log at startup to make it visible. At minimum, the comment block in initOORActor should call this out explicitly (and ideally a startup log line). As-is, it's a silent failure path that will confuse someone debugging an incoming OOR receive. Also worth adding a TODO linking to the follow-up issue.

Comment formatting typo in initOORActor

darepod/server.go:1602,1607 — Two lines in the block comment accidentally use a single / instead of //:

// WRONG (current):
/   - LocalPersistenceOutboxHandler: marks inputs spent, materializes
/   - SigningOutboxHandler (Next delegate): signs Ark and checkpoint

// RIGHT:
//   - LocalPersistenceOutboxHandler: marks inputs spent, materializes
//   - SigningOutboxHandler (Next delegate): signs Ark and checkpoint

Fix this →

mapRoundVTXOManagerMsg panics on unexpected types

darepod/server.go:1685-1692 — The function panics if msg doesn't implement vtxo.ManagerMsg. Given this is called from a MapInputRef in the hot message path, an unexpected type would crash the daemon rather than returning a handled error. A panic is defensible as a programmer error guard here, but it should at least be documented as intentional, or the wiring should use compile-time enforcement so it's impossible to reach at runtime.

Notification ordering in driveOutbox

oor/actor.go:955-993notifyMaterializedVTXOs fires before b.askEvent(ctx, fsm, followUp) and before persistCheckpoint. This means the VTXO manager may spawn an actor for a VTXO whose IncomingHandledEvent hasn't been committed to the OOR FSM checkpoint yet. If the process crashes between notification and checkpoint persistence, on restart the OOR FSM will re-emit the outbox (since checkpoint wasn't saved), call handleMaterializeIncoming again, SaveVTXO will see a duplicate and fetch the existing record, and notifyMaterializedVTXOs will send another notification — which the VTXO manager will handle with "VTXO actor already exists" and skip. So the correctness is maintained, but this subtle ordering invariant deserves a comment explaining why it's safe.

Idempotency check in handleMaterializeIncoming doesn't validate ChainDepth

oor/local_persistence_handler.go:236-248 — On a duplicate SaveVTXO error, the code fetches the existing record and considers it a match if Amount and PkScript agree. With ChainDepth now being meaningful, a retry path that supplies different metadata (e.g., corrected lineage) would silently use the original ChainDepth from the first materialization. This is probably fine given ChainDepth is authoritative from the metadata resolver (which would provide the same value on retry), but it's worth either expanding the equality check or adding a comment.

Minor nit: nil-descriptor guard inconsistency

vtxo/manager.go:216handleVTXOsMaterialized guards against nil descriptors with if descriptor == nil { continue }. The analogous handleVTXOCreated doesn't check for nil clientVTXO in its loop. These paths feed different message types so they're not exactly equivalent, but the defensive pattern is worth being consistent about.

Good things worth noting

  • The systest in systest/oor_vtxo_manager_test.go is thorough — it drives the full materialization path and asserts a live VTXO actor is spawned.
  • The ChainDepth documentation in vtxo.Descriptor is clear and correctly distinguishes it from TreeDepth.
  • The notifyMaterializedVTXOs approach (notification from the OOR behavior rather than the persistence handler) is the right place — the handler is a dumb I/O adapter, while the behavior owns the actor lifecycle semantics.
  • DB migration is correct — INTEGER NOT NULL DEFAULT 0 ensures backward compatibility for rows without the column.
  • clientVTXOToDescriptor explicitly sets ChainDepth: 0, which is self-documenting.

@ellemouton
ellemouton force-pushed the fix/oor-vtxo-manager-notify branch 2 times, most recently from 912e081 to 6d27ce9 Compare March 12, 2026 11:34
@ellemouton
ellemouton requested a review from Roasbeef March 12, 2026 18:51
Teach the OOR actor to forward durably materialized incoming VTXOs
into the VTXO manager.

This keeps OOR on the existing persist-then-notify architecture while
avoiding a second store write. The manager gains a dedicated message for
already-persisted descriptors, and focused unit tests cover the new
notifier wiring.
Start the VTXO manager actor during daemon startup and connect both
round completion notifications and OOR incoming materialization to it.

The round actor now supports late manager wiring so startup can bring the
manager online after the round actor is registered. Tests cover the late
binding path so the runtime wiring stays explicit and safe.
Add a systest that drives an incoming OOR receive through
materialization and asserts the VTXO manager activates the new
VTXO actor.

This covers the runtime wiring path that unit tests do not fully
exercise, including persistence, manager notification, and actor
registration in the live system graph.
Introduce ChainDepth as a first-class field on vtxo.Descriptor and
oor.IncomingVTXOMetadata, distinct from the existing TreeDepth.
TreeDepth tracks position within the VTXT (virtual transaction tree),
while ChainDepth counts OOR checkpoint hops from the last on-chain
commitment. Round-created VTXOs explicitly set ChainDepth to 0.

This is Part 2 of issue #124: the field is carried through the
domain types so that persistence and RPC layers can expose it in
follow-up commits.
Add migration 000005 with a chain_depth column (INTEGER NOT NULL
DEFAULT 0) to the vtxos table. Existing rows read as 0, which is the
correct value for round-created VTXOs and the safe default for
historical OOR VTXOs with unknown lineage.

Thread the field through both store implementations:
- VTXOPersistenceStore (OOR path): maps Descriptor.ChainDepth on
  insert and read.
- RoundPersistenceStore (round path): explicitly sets ChainDepth to 0.

The InsertVTXO ON CONFLICT clause preserves existing chain_depth when
the incoming value is 0, matching the pattern used for tree_depth and
batch_expiry.
Add chain_depth to the daemon VTXO message (field 10) and the indexer
VTXOInfo message (field 15). The daemon RPC server maps
Descriptor.ChainDepth into the new proto field so ListVTXOs callers
can inspect the OOR hop count.

This enables future tooling and metadata resolvers to consume chain
depth without another wire-format break.
Set ChainDepth to 2 in the systest incoming metadata fixture and
assert the persisted descriptor retains the value. This proves the
field flows through the OOR receive path and database round-trip in
the full actor-system integration test.
@Roasbeef
Roasbeef force-pushed the fix/oor-vtxo-manager-notify branch from 3c1896f to a4489c8 Compare March 13, 2026 21:31

@Roasbeef Roasbeef left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM 🌽

…nagerMsg

Replace the panic() in mapRoundVTXOManagerMsg with compile-time type
assertions that guarantee all round.VTXOManagerMsg implementors also
satisfy vtxo.ManagerMsg. This eliminates the runtime panic risk while
keeping the type assertion infallible.
Add an early validation check rejecting negative ChainDepth values in
the incoming VTXO descriptor builder. ChainDepth represents OOR
checkpoint hop count and is semantically non-negative.
Update CLAUDE.md and AGENTS.md for vtxo, oor, darepod, and db packages
to reflect new VTXOsMaterializedNotification message flow, ChainDepth
field on Descriptor, actor startup ordering invariants, and migration
000005 chain_depth column.
@Roasbeef
Roasbeef force-pushed the fix/oor-vtxo-manager-notify branch from a4489c8 to ef534be Compare March 13, 2026 21:44
@Roasbeef
Roasbeef merged commit 6fac4c2 into main Mar 13, 2026
16 checks passed
ellemouton added a commit that referenced this pull request Mar 19, 2026
oor: fix flaky TestOORServerRejectsTamperedFinalizeSignature
darioAnongba added a commit that referenced this pull request Aug 5, 2026
tap-sdk PR #173 adds the CallerSigned signing-plan variant needed to
classify lnd funding inputs on caller-funded anchors.
darioAnongba added a commit that referenced this pull request Aug 5, 2026
tap-sdk PR #173 (caller-signed anchor inputs) merged.
darioAnongba added a commit that referenced this pull request Aug 11, 2026
tap-sdk PR #173 adds the CallerSigned signing-plan variant needed to
classify lnd funding inputs on caller-funded anchors.
darioAnongba added a commit that referenced this pull request Aug 11, 2026
tap-sdk PR #173 (caller-signed anchor inputs) merged.
darioAnongba added a commit that referenced this pull request Aug 12, 2026
tap-sdk PR #173 adds the CallerSigned signing-plan variant needed to
classify lnd funding inputs on caller-funded anchors.
darioAnongba added a commit that referenced this pull request Aug 12, 2026
tap-sdk PR #173 (caller-signed anchor inputs) merged.
darioAnongba added a commit that referenced this pull request Aug 20, 2026
tap-sdk PR #173 adds the CallerSigned signing-plan variant needed to
classify lnd funding inputs on caller-funded anchors.
darioAnongba added a commit that referenced this pull request Aug 20, 2026
tap-sdk PR #173 (caller-signed anchor inputs) merged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants