Skip to content

multi: add Taproot Asset OOR and onboarding prototype - #1033

Closed
darioAnongba wants to merge 14 commits into
mainfrom
feat/taproot-assets-integration-refresh
Closed

multi: add Taproot Asset OOR and onboarding prototype#1033
darioAnongba wants to merge 14 commits into
mainfrom
feat/taproot-assets-integration-refresh

Conversation

@darioAnongba

Copy link
Copy Markdown
Collaborator

Summary

  • add an SDK-neutral Taproot Asset extension to Wavelength OOR packages and durable FSM snapshots
  • persist asset roots on VTXOs and compose them into checkpoint, forfeit, and timeout spend paths
  • integrate tap-sdk custom-anchor preparation inside waved while keeping tapd credentials out of the operator and swap daemon
  • materialize asset-aware incoming OOR VTXOs and retain sealed recovery packages
  • add direct confirmed Taproot Asset onboarding through LND WalletKit, operator registration, and wavecli

This is stack 1 of the Wavelength Taproot Assets PoC. It establishes the base single-input, send-all flow. Carrier-funded onboarding and managed carrier selection are separate follow-up PRs.

Architecture

Wavelength owns tapd access, proof selection, custom-anchor orchestration, signing, idempotency, and reconciliation. The operator receives only sealed packages, public policy data, and Bitcoin graph artifacts. Bitcoin-only paths remain unchanged.

Validation

  • make build
  • make unit
  • make lint-changed-local
  • focused lib/tx/oor, rpc/oorpb, oor, tapassets, waved, and CLI tests
  • go test -race ./tapassets ./waved

A live cross-repository regtest is intentionally left to the Lumos harness follow-up.

Prototype limits

The base slice moves one complete isolated asset anchor, uses one asset input and one recipient with exact carrier sats, requires a shared LND wallet between tapd and waved for onboarding, and persists unconfirmed proof paths without claiming an asset-only UX.

Add a versioned sealed-package container and bind optional Taproot Asset
roots to OOR input and recipient policies. Persist input and
start-message roots so durable retries can reconstruct the same composed
scripts.
Extend submit and offline-receive messages with optional asset roots and
the versioned sealed-package container. Keep Bitcoin-only payloads
backward compatible and validate asset bytes at the typed request
boundary.
Accept externally committed OOR graphs, validate them before signing,
and retain sealed Taproot Asset packages through durable actor messages,
FSM states, snapshots, and byte-identical submit retries.
Store the optional Taproot Asset commitment root with each VTXO and
derive composed policy scripts and spend control blocks for OOR,
forfeit, and unilateral exit paths. Exclude asset-bearing rows from
generic Bitcoin coin selection until rounds carry asset transitions.
Carry recipient commitment roots and sealed asset transition packages
through offline receive, durable actor snapshots, VTXO materialization,
and OOR artifact persistence. Preserve Bitcoin-only package behavior
while requiring asset-aware stores for asset sessions.
Add a proof-selected public intent and a restart-safe preparer seam so
Wavelength can commit an asset graph before its durable OOR actor signs
it. Keep Bitcoin-only sends unchanged and reject unsupported change,
missing adapters, and tampered results before actor submission.
Adapt the merged tap-sdk custom-anchor boundary to the Wavelength OOR
graph. Verify the selected tapd inventory, commit both transitions, and
persist outcome-aware replay state before the actor can sign.
Keep tapd credentials in the client daemon and install the adapter only
after explicit configuration. Preserve embedded config isolation and
document the PoC recovery and custody boundaries.
Document why ordinary round boarding cannot create the first
asset-bearing VTXO and record the fully rebased client validation
results.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fdb8aeea9c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tapassets/onboarding.go
Comment on lines +324 to +325
state.Registered = true
state.ConfirmationHeight = registration.ConfirmationHeight

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Persist registration intent before calling the operator

If the operator successfully admits the anchor but the daemon crashes (or storeState fails) before Registered is persisted, the next retry enters this branch and invokes RegisterTaprootAssetVTXO again. That RPC carries no idempotency key, so an operator that rejects an already-admitted outpoint will make the published asset permanently fail onboarding instead of letting the client materialize it locally. Journal an in-progress registration phase before the external call and provide a way to reconcile or idempotently replay the resulting admission.

Useful? React with 👍 / 👎.

@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 pull request introduces an experimental prototype for onboarding Taproot Assets into Wavelength VTXOs, adding new RPC endpoints (RegisterTaprootAssetVTXO and OnboardTaprootAsset), CLI commands, and database migrations to store Taproot Asset roots and transfer packages. It also updates the out-of-round (OOR) transfer logic to support asset-bearing transactions. Feedback on the changes highlights a potential issue in the VTXO insertion query (db/sqlc/queries/round.sql), where the taproot_asset_root is updated on conflict; since this root defines the output script, it should remain immutable to prevent inconsistencies with the on-chain state.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread db/sqlc/queries/round.sql
commitment_txid = CASE WHEN excluded.commitment_txid IS NOT NULL AND length(excluded.commitment_txid) > 0 THEN excluded.commitment_txid ELSE vtxos.commitment_txid END,
last_update_time = excluded.last_update_time;
commitment_txid = CASE WHEN excluded.commitment_txid IS NOT NULL AND length(excluded.commitment_txid) > 0 THEN excluded.commitment_txid ELSE vtxos.commitment_txid END,
taproot_asset_root = CASE WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 THEN excluded.taproot_asset_root ELSE vtxos.taproot_asset_root END,

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

The taproot_asset_root is part of the definition of the VTXO's output script and should be immutable once the VTXO is created. Updating it on conflict could lead to inconsistencies with the on-chain state, as the output script of a confirmed transaction cannot change. This field should be treated like other immutable properties (e.g., amount, expiry) and not be updated on conflict.

@litbot-9000

Copy link
Copy Markdown
Collaborator

@darioAnongba, remember to re-request review from reviewers when ready

@darioAnongba

Copy link
Copy Markdown
Collaborator Author

Superseded by #1062, which aggregates the full Taproot Asset OOR prototype stack (all files touched here are covered there).

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants