From 71bc12aed49891c9c7455e1b9fc7af2652930e24 Mon Sep 17 00:00:00 2001 From: Dario Anongba Varela Date: Tue, 21 Jul 2026 19:56:34 +0200 Subject: [PATCH 1/2] docs: plan durable Taproot Asset state --- docs/taproot-assets-asset-state-execplan.md | 312 ++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 docs/taproot-assets-asset-state-execplan.md diff --git a/docs/taproot-assets-asset-state-execplan.md b/docs/taproot-assets-asset-state-execplan.md new file mode 100644 index 000000000..02ee7a756 --- /dev/null +++ b/docs/taproot-assets-asset-state-execplan.md @@ -0,0 +1,312 @@ +# Persist asset state and mixed OOR package bindings + +This ExecPlan is a living document. The sections `Progress`, `Surprises & +Discoveries`, `Decision Log`, and `Outcomes & Retrospective` must be kept up to +date as work proceeds. This document is maintained in accordance with +`PLANS.md` at the repository root. + +## Purpose / Big Picture + +After this change, Wavelength can remember which Taproot Asset and how many +asset units a virtual transaction output (VTXO) carries without changing the +meaning of its Bitcoin amount. The existing `amount_sat` remains the explicit +carrier-satoshi value. A separate nested asset object returned by `ListVTXOs` +contains the opaque SDK-level asset reference, the full unsigned 64-bit asset +amount, and the 32-byte commitment root. + +The durable out-of-round (OOR) package format will also represent a graph that +contains one asset-bearing checkpoint and zero or more ordinary Bitcoin +checkpoints. Its checkpoint-package slice remains positional: every slot maps +to the checkpoint at the same index, a non-empty slot is a sealed Taproot Asset +transition, and an empty slot is a Bitcoin-only edge. Historical v0 containers +whose slots are all non-empty remain byte-for-byte readable. + +Finally, a caller preparing the next asset spend can ask the database for the +package that created an exact VTXO and can ask the `tapassets` adapter to derive +a restart-stable compact proof path and OP_TRUE asset witness from that sealed +package. This milestone does not yet construct a partial asset send. It builds +the SDK-neutral persistence, wire, and proof-source substrate that the next +stacked transaction-builder branch will consume. + +The behavior is observable in focused tests: a descriptor containing +`math.MaxUint64` asset units survives SQLite storage and `ListVTXOs`; mixed +asset/Bitcoin package slots survive encoding and reject ambiguous shapes; a +prepared graph accepts an asset input beside zero, one, or several Bitcoin +inputs; an outpoint with both created and consumed bindings resolves only its +created package; and decoding the same stored package before and after a +simulated restart returns identical proof-path and witness bytes. + +## Progress + +- [x] (2026-07-21 17:54Z) Audited the existing descriptor, migrations, + generated SQL, protobuf surfaces, OOR snapshots and durable TLVs, incoming + materialization, package bindings, and tap-sdk package projection. +- [x] (2026-07-21 17:54Z) Created + `feat/taproot-assets-asset-state` above + `feat/taproot-assets-carrier-selection` and wrote this living plan. +- [ ] Add SDK-neutral asset identity and amount to descriptor persistence and + the public VTXO projection, including a full-`uint64` database encoding. +- [ ] Propagate asset metadata through onboarding, recipient wire messages, + OOR snapshots and actor messages, and incoming VTXO materialization. +- [ ] Generalize the v0 sealed asset container and prepared-submit validation + for positional Bitcoin-only checkpoint slots and Bitcoin-only recipients. +- [ ] Add exact created-output package lookup and the tapassets proof-source + resolver/projection. +- [ ] Regenerate SQL/protobuf output, add comprehensive compatibility and + restart tests, and complete formatting, race, unit, build, lint, and commit + validation. + +## Surprises & Discoveries + +- Observation: the current v0 asset container already has the right positional + shape, but its package reader and writer reject zero-length checkpoint slots. + Evidence: `lib/tx/oor/asset_transfer.go` writes a length prefix per + checkpoint and `readTaprootAssetPackage` rejects length zero, so mixed graphs + need no new field or version, only explicit empty-slot semantics. +- Observation: an OOR outpoint can legitimately have both a + `created_output` binding and, after it is spent, a `consumed_input` binding. + Evidence: `db/sqlc/queries/oor_artifacts.sql` already has a kind-filtered + package query, while `OORArtifactPersistenceStore.GetPackageForOutpoint` + uses the unfiltered query and therefore cannot express proof-source intent. +- Observation: tap-sdk's sealed package already retains every item needed to + derive a later spend source, but Wavelength's current `commitResult` + projection discards most mappings and the input `ProofSource`. + Evidence: `tapassets/driver.go` currently projects only input outpoint, + asset reference, and amount, and projects output proof bytes by an + outpoint/script-key search. The upstream package additionally exposes stable + logical IDs, packet and virtual indices, anchor indices, proof-source kind + and bytes, script mode, and the exact OP_TRUE witness. + +## Decision Log + +- Decision: store `taproot_asset_amount` as an optional exactly eight-byte + big-endian BLOB, not SQL `BIGINT`. + Rationale: Taproot Asset amounts are `uint64`; both SQLite integer values and + Go's generated SQL integer fields are signed 64-bit. A fixed-width byte + encoding preserves `math.MaxUint64`, has one canonical representation, and + distinguishes historical metadata absence (`NULL`/empty) from a value. + Date/Author: 2026-07-21 / Codex. +- Decision: keep mixed checkpoint slots in TaprootAssetTransfer v0 rather than + introduce a sparse v1 map. + Rationale: the existing count and order already bind each slot to one + checkpoint. Accepting empty slots is backward compatible for every old + all-nonempty v0 payload, minimizes cross-repository churn, and keeps lookup + constant-time. Older binaries will reject newly mixed payloads, so + Wavelength and Lumos must deploy this feature together. + Date/Author: 2026-07-21 / Codex. +- Decision: allow historical asset-root-only descriptors to load, but require + new metadata producers to write asset reference and positive amount + together. + Rationale: migration 16 and already-persisted PoC outputs know only the + commitment root. Rejecting them would break existing databases. New + onboarding and OOR materialization paths have the identity and amount, so + silently producing another incomplete descriptor would be a bug. + Date/Author: 2026-07-21 / Codex. +- Decision: expose a dedicated created-output lookup rather than add a caller + parameter to the historical unfiltered lookup. + Rationale: existing unroll callers may intentionally resolve either link; + proof-source reconstruction specifically means “the package that created + this state” and should be impossible to call ambiguously. + Date/Author: 2026-07-21 / Codex. +- Decision: keep tap-sdk package decoding and compact proof-path construction + inside `tapassets` and return a narrow Wavelength projection. + Rationale: database, OOR, RPC, and operator surfaces must remain independent + of tapd and tap-sdk implementation types. The adapter can validate upstream + mappings once and return opaque proof bytes, plain strings and integers, + `wire.OutPoint`, and cloned witness stacks. + Date/Author: 2026-07-21 / Codex. + +## Outcomes & Retrospective + +Implementation is not complete yet. The current branch contains only this +plan. Update this section after each milestone with the exact behavior, test +evidence, compatibility consequences, and any remaining live integration gap. + +## Context and Orientation + +A VTXO is Wavelength's spendable virtual Bitcoin output. Its +`vtxo.Descriptor.Amount` and the public `waverpc.VTXO.amount_sat` describe the +Bitcoin satoshis carried by the output. Taproot Asset units are a separate +quantity and must never be added to or substituted for those satoshis. + +`vtxo/interfaces.go` defines the canonical descriptor. `db/vtxo_store.go` +maps it to the `vtxos` table. SQL migration sources live under +`db/sqlc/migrations`, and query sources live under `db/sqlc/queries`; generated +files under `db/sqlc` must only be changed by `make sqlc` or the repository's +exact pinned local generator. Migration 16 added `taproot_asset_root`, and this +branch appends migration 18 for the asset reference and amount. The nested +public asset projection belongs in `waverpc/daemon.proto` and is populated by +`waved.descriptorToProto`. + +An OOR transfer has one checkpoint transaction per selected input and one Ark +transaction that spends every checkpoint into recipient outputs. The shared +container `lib/tx/oor.TaprootAssetTransfer` stores sealed tap-sdk packages while +keeping them opaque outside the `tapassets` package. `oor.PreparedSubmitPackage` +binds that container to concrete transfer inputs, checkpoints, and recipients. +For a mixed graph, root presence on input `i` must exactly equal package-slot +presence at index `i`; Bitcoin-only inputs have neither. + +Recipient metadata crosses several durable boundaries. The canonical domain +type is `lib/tx/oor.RecipientOutput`; `rpc/oorpb/oorwire.proto` carries it to +the operator; `arkrpc/indexer.proto` carries it back in recipient and VTXO +events; `oor/actor_durable_message.go` and +`oor/outgoing_snapshot_codec.go` retain it across actor restarts; and +`oor/local_persistence_handler.go` plus `oor/incoming_vtxo.go` materialize the +descriptor. New TLV record numbers must be append-only so historical actor +messages and snapshots continue to decode with zero-valued optional fields. + +`db.OORArtifactPersistenceStore` stores sealed packages and outpoint +bindings. A created-output binding links a local VTXO to the package whose Ark +transaction created it; a consumed-input binding links the same outpoint to a +later package that spent it. `GetOORPackageByOutpointAndKind` already exists in +generated SQL and is the correct primitive for an unambiguous +`GetCreatedPackageForOutpoint` method. + +The only package allowed to import tap-sdk is `tapassets`. A sealed +`tapsdk.CustomAnchorTransferPackage` contains input proof sources, output +logical and virtual mappings, transition proof updates, script modes, and +OP_TRUE witness data. The new resolver validates that package, finds the exact +output by anchor outpoint plus asset identity and amount, requires a unique +matching proof update, reconstructs an `AssetProofPath` from either a confirmed +proof file or an existing compact path, appends the output transition, and +returns cloned opaque bytes and witness elements. + +## Plan of Work + +First, append migration 18 with nullable `taproot_asset_ref TEXT` and +`taproot_asset_amount BLOB` columns. Extend the VTXO insert/upsert query and all +generated projections. Add documented encode/decode helpers in +`db/vtxo_store.go` that only emit eight-byte big-endian amounts and reject any +other non-empty length. Extend `vtxo.Descriptor` and the cache-safe row mapping. +Add a nested `TaprootAssetVTXO` message to `waverpc/daemon.proto`, leaving +`amount_sat` unchanged, and populate it only when a descriptor has a root. + +Next, carry reference, amount, and root through every asset recipient path. +Extend `RecipientOutput`, `ArkRecipientOutput`, OOR protobuf recipient fields, +indexer recipient/VTXO event fields, recipient TLV payloads, outgoing +snapshots, incoming events, cloning helpers, and descriptor construction. +Append TLV record types without renumbering existing fields. Extend +`TransferInputSnapshot` so a restart retains the selected descriptor's asset +metadata. Add asset identity and amount to `tapassets.OnboardingResult` and +materialize them in the direct-on-chain descriptor. All new metadata must use +plain strings, byte arrays, and integers outside `tapassets`. + +Then change `TaprootAssetTransfer.Validate`, marshal, and unmarshal so empty +checkpoint slots are legal only as Bitcoin-only placeholders. The slice must +remain non-empty, must equal the expected checkpoint count, must contain at +least one non-empty slot, and must have a non-empty bounded Ark package. Keep +the checksum and v0 binary envelope unchanged. Update +`PreparedSubmitPackage.Validate` so each input root is present exactly when its +slot is non-empty. Validate asset commitments only for recipients with roots; +allow ordinary Bitcoin recipients and require at least one asset-bearing +recipient. + +Add `GetCreatedPackageForOutpoint` to `db.OORArtifactPersistenceStore`. Reuse +the existing kind-filtered query inside one read transaction and materialize +the matching binding exactly as the historical method does. Leave +`GetPackageForOutpoint` unchanged for compatibility. In `tapassets/driver.go`, +retain all upstream logical IDs, packet roles and indices, anchor indices, +input proof source fields, output script mode, and exact proof-update mapping. +Add a narrow resolver that converts the sealed Ark package and exact created +outpoint into a validated, restart-stable proof source and OP_TRUE witness. + +Finally, add tests at each boundary. Cover mixed and historical all-nonempty v0 +container round trips, all-empty/count/size corruption, prepared asset plus +zero/one/many Bitcoin inputs and recipients, database max-`uint64` and invalid +BLOB lengths, onboarding and incoming metadata propagation, OOR proto and TLV +round trips with old-field omission, `ListVTXOs`, created-versus-consumed +binding ambiguity, resolver mismatch/duplicate/missing update failures, and +restart byte equality. Regenerate code, format changed files, and run focused +tests and their race variants before the full unit/build/lint gates. + +## Concrete Steps + +Work from: + + cd /Users/dario/dev/lightninglabs/.worktrees/wavelength-carrier-funding + +After SQL and protobuf source edits, regenerate rather than editing generated +files: + + make sqlc + make rpc + +If those Docker wrappers cannot connect to the Docker daemon, inspect the +Makefile/tool manifests and run the exact pinned local sqlc and protobuf tools. +Record the versions and reason in `Surprises & Discoveries`. + +Format and run focused packages throughout: + + make fmt-changed + go test ./lib/tx/oor ./db ./vtxo ./rpc/oorpb ./oor ./tapassets ./waved + go test -race ./lib/tx/oor ./db ./vtxo ./rpc/oorpb ./oor ./tapassets ./waved + +Before the implementation commit, run: + + make unit + make build + make lint-changed-local + make commitmsg-lint range="origin/main..HEAD" + +## Validation and Acceptance + +Acceptance requires all focused and repository tests to pass and the following +behaviors to be pinned by tests. A descriptor with an asset reference, root, +and `math.MaxUint64` amount must save and load exactly and must appear through +`descriptorToProto` with the satoshi carrier value unchanged. An old row with +only an asset root must still load and list with a present asset object whose +reference and amount are absent/zero. + +A v0 transfer with slots `[asset-package, empty, empty]` must marshal and +unmarshal exactly, while `[empty, empty]`, a checkpoint-count mismatch, an +empty Ark package, an oversized package, a bad checksum, and trailing bytes +must fail. Historical `[asset-package, asset-package]` bytes must continue to +decode. Prepared-submit tests must accept every supported mixed input/output +shape and reject every disagreement between input roots and package slots. + +When one outpoint has a created binding to package A and a consumed binding to +package B, `GetCreatedPackageForOutpoint` must always return A and report the +created binding. The proof resolver must derive one compact path with the +package output's transition proof, return the exact OP_TRUE witness, reject a +wrong outpoint/ref/amount, ambiguous or missing proof updates, and a non-OP_TRUE +output, and return byte-identical results after reloading the same stored +package. + +## Idempotence and Recovery + +Migration 18 is additive and safe to retry through the repository migrator. +All historical rows decode because both columns are nullable. SQL regeneration +is deterministic. Protobuf and TLV fields are append-only, so omitted fields +decode to empty values and old messages remain accepted. + +Package and proof-source methods do not mutate stored or caller-owned byte +slices. Every returned blob and witness stack is cloned. Re-running a focused +test or decoding the same sealed package after restart therefore produces the +same bytes without external tapd calls. + +## Artifacts and Notes + +This branch is stacked on commit `dda6a523`, the carrier-selection milestone. +The next branch will use this substrate to build a partial asset transfer such +as 1,000 units to 800 receiver plus 200 change, funded by explicit carrier +satoshis. The cross-repository live test belongs in Lumos once its validator +understands the same positional empty-slot semantics. + +## Interfaces and Dependencies + +At completion, `vtxo.Descriptor` has `TaprootAssetRef string`, +`TaprootAssetAmount uint64`, and the existing +`TaprootAssetRoot *chainhash.Hash`. `waverpc.VTXO` has an optional nested +asset message; its existing `amount_sat` contract is unchanged. + +`lib/tx/oor.TaprootAssetTransfer.CheckpointPackages` remains `[][]byte`, but +an empty element has the defined meaning “the checkpoint at this index is +Bitcoin-only.” `oor.PreparedSubmitPackage.Validate` enforces package-slot and +input-root equivalence and mixed recipients. + +`db.OORArtifactPersistenceStore.GetCreatedPackageForOutpoint` returns the +existing SDK-neutral `OORPackageBundle`. The new `tapassets` resolver accepts +sealed package bytes plus SDK-neutral output identity and returns a projection +containing compact proof-path bytes, asset reference and amount, anchor output +index/outpoint, stable logical and packet mappings, and a cloned OP_TRUE +witness. No non-`tapassets` package imports tap-sdk or taproot-assets. From abbf78344dffa068ce57ec22dc011b874f2ff407 Mon Sep 17 00:00:00 2001 From: Dario Anongba Varela Date: Tue, 21 Jul 2026 20:33:40 +0200 Subject: [PATCH 2/2] tapassets: persist asset state for mixed OOR transfers Keep carrier satoshis separate from durable SDK-neutral asset identity and quantity. Carry that state through onboarding, RPC, OOR snapshots, incoming materialization, and operator signing descriptors. Support positional Bitcoin-only slots in Taproot Asset packages and reconstruct restart-stable spend proof sources from exact created-output package bindings. --- arkrpc/ark.pb.go | 30 +- arkrpc/ark.proto | 8 + arkrpc/indexer.pb.go | 112 +- arkrpc/indexer.proto | 32 + db/AGENTS.md | 6 +- db/migrations.go | 2 +- db/oor_artifact_store.go | 64 + db/oor_artifact_store_test.go | 18 + ...00018_taproot_asset_vtxo_metadata.down.sql | 2 + .../000018_taproot_asset_vtxo_metadata.up.sql | 6 + db/sqlc/models.go | 2 + db/sqlc/queries/round.sql | 31 +- db/sqlc/round.sql.go | 51 +- db/sqlc/schemas/generated_schema.sql | 16 +- db/sqlc/vtxo.sql.go | 8 +- db/vtxo_store.go | 127 +- db/vtxo_store_test.go | 251 ++++ docs/taproot-assets-asset-state-execplan.md | 56 +- lib/tx/oor/asset_transfer.go | 65 +- lib/tx/oor/asset_transfer_test.go | 44 +- lib/tx/oor/build.go | 46 + oor/actor_durable_message.go | 149 +- oor/actor_durable_message_test.go | 13 + oor/actor_messages.go | 8 +- oor/ark_recipients.go | 10 + oor/incoming_adapter.go | 30 +- oor/incoming_adapter_test.go | 19 + oor/incoming_vtxo.go | 55 +- oor/incoming_vtxo_test.go | 18 +- oor/local_persistence_handler.go | 10 +- oor/local_persistence_handler_test.go | 10 +- oor/outbox_error_test.go | 9 +- oor/outbox_messages.go | 2 + oor/outgoing_snapshot.go | 11 +- oor/outgoing_snapshot_codec.go | 8 + oor/prepared_submit.go | 20 +- oor/prepared_submit_test.go | 131 +- oor/receive_snapshot.go | 5 +- oor/taproot_asset_preparer.go | 2 +- oor/transfer_input_snapshot.go | 21 +- oor/transfer_input_snapshot_test.go | 35 +- oor/transfer_inputs.go | 24 + rpc/oorpb/oorwire.pb.go | 56 +- rpc/oorpb/oorwire.proto | 14 + rpc/oorpb/payloads.go | 49 +- rpc/oorpb/payloads_property_test.go | 33 + rpc/oorpb/payloads_test.go | 161 ++- tapassets/driver.go | 114 +- tapassets/onboarding.go | 21 +- tapassets/onboarding_test.go | 6 + tapassets/preparer.go | 2 + tapassets/preparer_test.go | 16 +- tapassets/proof_source.go | 255 ++++ tapassets/proof_source_test.go | 521 +++++++ vtxo/incoming_handler.go | 144 +- vtxo/incoming_handler_test.go | 57 + vtxo/interfaces.go | 15 + waved/rpc_server.go | 7 + waved/rpc_swap_lookup.go | 18 +- waved/rpc_taproot_asset_onboarding.go | 17 +- waved/rpc_taproot_asset_onboarding_test.go | 21 +- waved/rpc_vtxo_settlement_test.go | 55 + waved/taproot_asset_metadata.go | 51 + waved/wallet_recovery.go | 34 +- waverpc/daemon.pb.go | 1288 +++++++++-------- waverpc/daemon.proto | 17 + 66 files changed, 3700 insertions(+), 839 deletions(-) create mode 100644 db/sqlc/migrations/000018_taproot_asset_vtxo_metadata.down.sql create mode 100644 db/sqlc/migrations/000018_taproot_asset_vtxo_metadata.up.sql create mode 100644 tapassets/proof_source.go create mode 100644 tapassets/proof_source_test.go create mode 100644 waved/taproot_asset_metadata.go diff --git a/arkrpc/ark.pb.go b/arkrpc/ark.pb.go index 7252fb166..2deee9591 100644 --- a/arkrpc/ark.pb.go +++ b/arkrpc/ark.pb.go @@ -88,8 +88,14 @@ type RegisterTaprootAssetVTXORequest struct { // taproot_asset_root is repeated explicitly so cheap request bounds and // script composition checks can run before persistence. TaprootAssetRoot []byte `protobuf:"bytes,4,opt,name=taproot_asset_root,json=taprootAssetRoot,proto3" json:"taproot_asset_root,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // taproot_asset_ref is the opaque SDK-level asset identity committed by + // the sealed package. + TaprootAssetRef string `protobuf:"bytes,5,opt,name=taproot_asset_ref,json=taprootAssetRef,proto3" json:"taproot_asset_ref,omitempty"` + // taproot_asset_amount is the number of asset units in the admitted + // output. The anchor output value remains carrier satoshis. + TaprootAssetAmount uint64 `protobuf:"varint,6,opt,name=taproot_asset_amount,json=taprootAssetAmount,proto3" json:"taproot_asset_amount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *RegisterTaprootAssetVTXORequest) Reset() { @@ -150,6 +156,20 @@ func (x *RegisterTaprootAssetVTXORequest) GetTaprootAssetRoot() []byte { return nil } +func (x *RegisterTaprootAssetVTXORequest) GetTaprootAssetRef() string { + if x != nil { + return x.TaprootAssetRef + } + return "" +} + +func (x *RegisterTaprootAssetVTXORequest) GetTaprootAssetAmount() uint64 { + if x != nil { + return x.TaprootAssetAmount + } + return 0 +} + type RegisterTaprootAssetVTXOResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // txid and output_index identify the admitted direct on-chain VTXO. @@ -738,12 +758,14 @@ var File_ark_proto protoreflect.FileDescriptor const file_ark_proto_rawDesc = "" + "\n" + - "\tark.proto\x12\x06arkrpc\"\xd8\x01\n" + + "\tark.proto\x12\x06arkrpc\"\xb6\x02\n" + "\x1fRegisterTaprootAssetVTXORequest\x12)\n" + "\x10transfer_package\x18\x01 \x01(\fR\x0ftransferPackage\x12*\n" + "\x11final_anchor_psbt\x18\x02 \x01(\fR\x0ffinalAnchorPsbt\x120\n" + "\x14vtxo_policy_template\x18\x03 \x01(\fR\x12vtxoPolicyTemplate\x12,\n" + - "\x12taproot_asset_root\x18\x04 \x01(\fR\x10taprootAssetRoot\"\x8a\x01\n" + + "\x12taproot_asset_root\x18\x04 \x01(\fR\x10taprootAssetRoot\x12*\n" + + "\x11taproot_asset_ref\x18\x05 \x01(\tR\x0ftaprootAssetRef\x120\n" + + "\x14taproot_asset_amount\x18\x06 \x01(\x04R\x12taprootAssetAmount\"\x8a\x01\n" + " RegisterTaprootAssetVTXOResponse\x12\x12\n" + "\x04txid\x18\x01 \x01(\fR\x04txid\x12!\n" + "\foutput_index\x18\x02 \x01(\rR\voutputIndex\x12/\n" + diff --git a/arkrpc/ark.proto b/arkrpc/ark.proto index 7c25ba42e..b947c9dd9 100644 --- a/arkrpc/ark.proto +++ b/arkrpc/ark.proto @@ -35,6 +35,14 @@ message RegisterTaprootAssetVTXORequest { // taproot_asset_root is repeated explicitly so cheap request bounds and // script composition checks can run before persistence. bytes taproot_asset_root = 4; + + // taproot_asset_ref is the opaque SDK-level asset identity committed by + // the sealed package. + string taproot_asset_ref = 5; + + // taproot_asset_amount is the number of asset units in the admitted + // output. The anchor output value remains carrier satoshis. + uint64 taproot_asset_amount = 6; } message RegisterTaprootAssetVTXOResponse { diff --git a/arkrpc/indexer.pb.go b/arkrpc/indexer.pb.go index a1758edc4..24e27045d 100644 --- a/arkrpc/indexer.pb.go +++ b/arkrpc/indexer.pb.go @@ -941,8 +941,14 @@ type OORRecipientEvent struct { // taproot_asset_transfer is the optional versioned Wavelength container // of sealed tap-sdk packages for the checkpoint and Ark transitions. TaprootAssetTransfer []byte `protobuf:"bytes,11,opt,name=taproot_asset_transfer,json=taprootAssetTransfer,proto3" json:"taproot_asset_transfer,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this recipient output. + TaprootAssetRef string `protobuf:"bytes,12,opt,name=taproot_asset_ref,json=taprootAssetRef,proto3" json:"taproot_asset_ref,omitempty"` + // taproot_asset_amount is the number of asset units carried by this + // output. value remains the separate Bitcoin carrier amount. + TaprootAssetAmount uint64 `protobuf:"varint,13,opt,name=taproot_asset_amount,json=taprootAssetAmount,proto3" json:"taproot_asset_amount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *OORRecipientEvent) Reset() { @@ -1052,6 +1058,20 @@ func (x *OORRecipientEvent) GetTaprootAssetTransfer() []byte { return nil } +func (x *OORRecipientEvent) GetTaprootAssetRef() string { + if x != nil { + return x.TaprootAssetRef + } + return "" +} + +func (x *OORRecipientEvent) GetTaprootAssetAmount() uint64 { + if x != nil { + return x.TaprootAssetAmount + } + return 0 +} + // OORSessionPackage carries finalized package artifacts for one OOR session. type OORSessionPackage struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1759,8 +1779,17 @@ type VTXO struct { // IncomingVTXOEvent) does not yet carry this field and adopts it as a // fast-follow. Today the only understood value is 1. ConstructionVersion uint32 `protobuf:"varint,20,opt,name=construction_version,json=constructionVersion,proto3" json:"construction_version,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // taproot_asset_root is the optional 32-byte Taproot Asset commitment + // root anchored in this VTXO. + TaprootAssetRoot []byte `protobuf:"bytes,21,opt,name=taproot_asset_root,json=taprootAssetRoot,proto3" json:"taproot_asset_root,omitempty"` + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this VTXO. + TaprootAssetRef string `protobuf:"bytes,22,opt,name=taproot_asset_ref,json=taprootAssetRef,proto3" json:"taproot_asset_ref,omitempty"` + // taproot_asset_amount is the number of asset units carried by this VTXO. + // value_sat remains the separate Bitcoin carrier value. + TaprootAssetAmount uint64 `protobuf:"varint,23,opt,name=taproot_asset_amount,json=taprootAssetAmount,proto3" json:"taproot_asset_amount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *VTXO) Reset() { @@ -1919,6 +1948,27 @@ func (x *VTXO) GetConstructionVersion() uint32 { return 0 } +func (x *VTXO) GetTaprootAssetRoot() []byte { + if x != nil { + return x.TaprootAssetRoot + } + return nil +} + +func (x *VTXO) GetTaprootAssetRef() string { + if x != nil { + return x.TaprootAssetRef + } + return "" +} + +func (x *VTXO) GetTaprootAssetAmount() uint64 { + if x != nil { + return x.TaprootAssetAmount + } + return 0 +} + type ListVTXOsByScriptsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Scripts []*ScriptScope `protobuf:"bytes,1,rep,name=scripts,proto3" json:"scripts,omitempty"` @@ -2632,8 +2682,17 @@ type IncomingVTXOEvent struct { // commitment transaction. This is distinct from the leaf txid // carried in the outpoint field. CommitmentTxid []byte `protobuf:"bytes,11,opt,name=commitment_txid,json=commitmentTxid,proto3" json:"commitment_txid,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // taproot_asset_root is the optional 32-byte Taproot Asset commitment + // root anchored in this VTXO. + TaprootAssetRoot []byte `protobuf:"bytes,12,opt,name=taproot_asset_root,json=taprootAssetRoot,proto3" json:"taproot_asset_root,omitempty"` + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this VTXO. + TaprootAssetRef string `protobuf:"bytes,13,opt,name=taproot_asset_ref,json=taprootAssetRef,proto3" json:"taproot_asset_ref,omitempty"` + // taproot_asset_amount is the number of asset units carried by this VTXO. + // value_sat remains the separate Bitcoin carrier value. + TaprootAssetAmount uint64 `protobuf:"varint,14,opt,name=taproot_asset_amount,json=taprootAssetAmount,proto3" json:"taproot_asset_amount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *IncomingVTXOEvent) Reset() { @@ -2743,6 +2802,27 @@ func (x *IncomingVTXOEvent) GetCommitmentTxid() []byte { return nil } +func (x *IncomingVTXOEvent) GetTaprootAssetRoot() []byte { + if x != nil { + return x.TaprootAssetRoot + } + return nil +} + +func (x *IncomingVTXOEvent) GetTaprootAssetRef() string { + if x != nil { + return x.TaprootAssetRef + } + return "" +} + +func (x *IncomingVTXOEvent) GetTaprootAssetAmount() uint64 { + if x != nil { + return x.TaprootAssetAmount + } + return 0 +} + var File_indexer_proto protoreflect.FileDescriptor const file_indexer_proto_rawDesc = "" + @@ -2788,7 +2868,7 @@ const file_indexer_proto_rawDesc = "" + "&ListOORRecipientEventsByScriptResponse\x121\n" + "\x06events\x18\x01 \x03(\v2\x19.arkrpc.OORRecipientEventR\x06events\x12\x1f\n" + "\vnext_cursor\x18\x02 \x01(\x04R\n" + - "nextCursor\"\xda\x03\n" + + "nextCursor\"\xb8\x04\n" + "\x11OORRecipientEvent\x12.\n" + "\x13recipient_pk_script\x18\x01 \x01(\fR\x11recipientPkScript\x12\x19\n" + "\bevent_id\x18\x02 \x01(\x04R\aeventId\x12\x1d\n" + @@ -2802,7 +2882,9 @@ const file_indexer_proto_rawDesc = "" + "\x14vtxo_policy_template\x18\t \x01(\fR\x12vtxoPolicyTemplate\x12,\n" + "\x12taproot_asset_root\x18\n" + " \x01(\fR\x10taprootAssetRoot\x124\n" + - "\x16taproot_asset_transfer\x18\v \x01(\fR\x14taprootAssetTransfer\"\xae\x01\n" + + "\x16taproot_asset_transfer\x18\v \x01(\fR\x14taprootAssetTransfer\x12*\n" + + "\x11taproot_asset_ref\x18\f \x01(\tR\x0ftaprootAssetRef\x120\n" + + "\x14taproot_asset_amount\x18\r \x01(\x04R\x12taprootAssetAmount\"\xae\x01\n" + "\x11OORSessionPackage\x12\x1d\n" + "\n" + "session_id\x18\x01 \x01(\fR\tsessionId\x12\x19\n" + @@ -2850,7 +2932,7 @@ const file_indexer_proto_rawDesc = "" + "\x0ftaproot_schnorr\x18\n" + " \x01(\v2\x1b.arkrpc.TaprootSchnorrProofH\x00R\x0etaprootSchnorr\x12-\n" + "\x06bip322\x18\v \x01(\v2\x13.arkrpc.BIP322ProofH\x00R\x06bip322B\a\n" + - "\x05proof\"\xe2\x05\n" + + "\x05proof\"\xee\x06\n" + "\x04VTXO\x12,\n" + "\boutpoint\x18\x01 \x01(\v2\x10.arkrpc.OutPointR\boutpoint\x12\x1b\n" + "\tvalue_sat\x18\x02 \x01(\x04R\bvalueSat\x12\x1b\n" + @@ -2872,7 +2954,10 @@ const file_indexer_proto_rawDesc = "" + "\rspent_by_txid\x18\x11 \x01(\fR\vspentByTxid\x12;\n" + "\x0eancestry_paths\x18\x12 \x03(\v2\x14.arkrpc.AncestryPathR\rancestryPaths\x12'\n" + "\x0foperator_pubkey\x18\x13 \x01(\fR\x0eoperatorPubkey\x121\n" + - "\x14construction_version\x18\x14 \x01(\rR\x13constructionVersion\"\xb1\x01\n" + + "\x14construction_version\x18\x14 \x01(\rR\x13constructionVersion\x12,\n" + + "\x12taproot_asset_root\x18\x15 \x01(\fR\x10taprootAssetRoot\x12*\n" + + "\x11taproot_asset_ref\x18\x16 \x01(\tR\x0ftaprootAssetRef\x120\n" + + "\x14taproot_asset_amount\x18\x17 \x01(\x04R\x12taprootAssetAmount\"\xb1\x01\n" + "\x19ListVTXOsByScriptsRequest\x12-\n" + "\ascripts\x18\x01 \x03(\v2\x13.arkrpc.ScriptScopeR\ascripts\x127\n" + "\rstatus_filter\x18\x02 \x03(\x0e2\x12.arkrpc.VTXOStatusR\fstatusFilter\x12\x16\n" + @@ -2920,7 +3005,7 @@ const file_indexer_proto_rawDesc = "" + "\x1fListVTXOEventsByScriptsResponse\x12)\n" + "\x06events\x18\x01 \x03(\v2\x11.arkrpc.VTXOEventR\x06events\x12\x1f\n" + "\vnext_cursor\x18\x02 \x01(\x04R\n" + - "nextCursor\"\xb6\x03\n" + + "nextCursor\"\xc2\x04\n" + "\x11IncomingVTXOEvent\x12\x19\n" + "\bevent_id\x18\x01 \x01(\x04R\aeventId\x12)\n" + "\x04type\x18\x02 \x01(\x0e2\x15.arkrpc.VTXOEventTypeR\x04type\x12,\n" + @@ -2933,7 +3018,10 @@ const file_indexer_proto_rawDesc = "" + "\x0frelative_expiry\x18\t \x01(\rR\x0erelativeExpiry\x12*\n" + "\x06origin\x18\n" + " \x01(\x0e2\x12.arkrpc.VTXOOriginR\x06origin\x12'\n" + - "\x0fcommitment_txid\x18\v \x01(\fR\x0ecommitmentTxid*\x84\x02\n" + + "\x0fcommitment_txid\x18\v \x01(\fR\x0ecommitmentTxid\x12,\n" + + "\x12taproot_asset_root\x18\f \x01(\fR\x10taprootAssetRoot\x12*\n" + + "\x11taproot_asset_ref\x18\r \x01(\tR\x0ftaprootAssetRef\x120\n" + + "\x14taproot_asset_amount\x18\x0e \x01(\x04R\x12taprootAssetAmount*\x84\x02\n" + "\n" + "VTXOStatus\x12\x1b\n" + "\x17VTXO_STATUS_UNSPECIFIED\x10\x00\x12\x1b\n" + diff --git a/arkrpc/indexer.proto b/arkrpc/indexer.proto index 1032f2a57..6347a4a81 100644 --- a/arkrpc/indexer.proto +++ b/arkrpc/indexer.proto @@ -195,6 +195,14 @@ message OORRecipientEvent { // taproot_asset_transfer is the optional versioned Wavelength container // of sealed tap-sdk packages for the checkpoint and Ark transitions. bytes taproot_asset_transfer = 11; + + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this recipient output. + string taproot_asset_ref = 12; + + // taproot_asset_amount is the number of asset units carried by this + // output. value remains the separate Bitcoin carrier amount. + uint64 taproot_asset_amount = 13; } // OORSessionPackage carries finalized package artifacts for one OOR session. @@ -468,6 +476,18 @@ message VTXO { // IncomingVTXOEvent) does not yet carry this field and adopts it as a // fast-follow. Today the only understood value is 1. uint32 construction_version = 20; + + // taproot_asset_root is the optional 32-byte Taproot Asset commitment + // root anchored in this VTXO. + bytes taproot_asset_root = 21; + + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this VTXO. + string taproot_asset_ref = 22; + + // taproot_asset_amount is the number of asset units carried by this VTXO. + // value_sat remains the separate Bitcoin carrier value. + uint64 taproot_asset_amount = 23; } message ListVTXOsByScriptsRequest { @@ -642,4 +662,16 @@ message IncomingVTXOEvent { // commitment transaction. This is distinct from the leaf txid // carried in the outpoint field. bytes commitment_txid = 11; + + // taproot_asset_root is the optional 32-byte Taproot Asset commitment + // root anchored in this VTXO. + bytes taproot_asset_root = 12; + + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this VTXO. + string taproot_asset_ref = 13; + + // taproot_asset_amount is the number of asset units carried by this VTXO. + // value_sat remains the separate Bitcoin carrier value. + uint64 taproot_asset_amount = 14; } diff --git a/db/AGENTS.md b/db/AGENTS.md index 7831323ed..640eb8c97 100644 --- a/db/AGENTS.md +++ b/db/AGENTS.md @@ -71,7 +71,7 @@ For field-level detail, use `go doc github.com/lightninglabs/wavelength/db. 0 THEN excluded.pk_script ELSE vtxos.pk_script END, @@ -150,7 +151,31 @@ ON CONFLICT (outpoint_hash, outpoint_index) DO UPDATE SET chain_depth = CASE WHEN excluded.chain_depth != 0 THEN excluded.chain_depth ELSE vtxos.chain_depth END, created_height = CASE WHEN excluded.created_height != 0 THEN excluded.created_height ELSE vtxos.created_height END, 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, + taproot_asset_root = CASE + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND excluded.taproot_asset_ref IS NOT NULL AND length(excluded.taproot_asset_ref) > 0 + AND excluded.taproot_asset_amount IS NOT NULL AND length(excluded.taproot_asset_amount) > 0 + THEN excluded.taproot_asset_root + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND (vtxos.taproot_asset_ref IS NULL OR length(vtxos.taproot_asset_ref) = 0) + AND (vtxos.taproot_asset_amount IS NULL OR length(vtxos.taproot_asset_amount) = 0) + THEN excluded.taproot_asset_root + ELSE vtxos.taproot_asset_root + END, + taproot_asset_ref = CASE + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND excluded.taproot_asset_ref IS NOT NULL AND length(excluded.taproot_asset_ref) > 0 + AND excluded.taproot_asset_amount IS NOT NULL AND length(excluded.taproot_asset_amount) > 0 + THEN excluded.taproot_asset_ref + ELSE vtxos.taproot_asset_ref + END, + taproot_asset_amount = CASE + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND excluded.taproot_asset_ref IS NOT NULL AND length(excluded.taproot_asset_ref) > 0 + AND excluded.taproot_asset_amount IS NOT NULL AND length(excluded.taproot_asset_amount) > 0 + THEN excluded.taproot_asset_amount + ELSE vtxos.taproot_asset_amount + END, last_update_time = excluded.last_update_time; -- name: InsertVTXOAncestryPath :exec diff --git a/db/sqlc/round.sql.go b/db/sqlc/round.sql.go index ddc105af4..6507f51c2 100644 --- a/db/sqlc/round.sql.go +++ b/db/sqlc/round.sql.go @@ -323,7 +323,7 @@ func (q *Queries) GetRoundVtxoRequests(ctx context.Context, roundID string) ([]R } const GetVTXO = `-- name: GetVTXO :one -SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root FROM vtxos +SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root, taproot_asset_ref, taproot_asset_amount FROM vtxos WHERE outpoint_hash = $1 AND outpoint_index = $2 ` @@ -360,6 +360,8 @@ func (q *Queries) GetVTXO(ctx context.Context, arg GetVTXOParams) (Vtxo, error) &i.ChainDepth, &i.ConstructionVersion, &i.TaprootAssetRoot, + &i.TaprootAssetRef, + &i.TaprootAssetAmount, ) return i, err } @@ -547,10 +549,11 @@ INSERT INTO vtxos ( policy_template, client_key_id, operator_pubkey, batch_expiry, chain_depth, created_height, commitment_txid, spent, creation_time, last_update_time, - construction_version, taproot_asset_root + construction_version, taproot_asset_root, taproot_asset_ref, + taproot_asset_amount ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, - $17, $18 + $17, $18, $19, $20 ) ON CONFLICT (outpoint_hash, outpoint_index) DO UPDATE SET pk_script = CASE WHEN excluded.pk_script IS NOT NULL AND length(excluded.pk_script) > 0 THEN excluded.pk_script ELSE vtxos.pk_script END, @@ -562,7 +565,31 @@ ON CONFLICT (outpoint_hash, outpoint_index) DO UPDATE SET chain_depth = CASE WHEN excluded.chain_depth != 0 THEN excluded.chain_depth ELSE vtxos.chain_depth END, created_height = CASE WHEN excluded.created_height != 0 THEN excluded.created_height ELSE vtxos.created_height END, 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, + taproot_asset_root = CASE + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND excluded.taproot_asset_ref IS NOT NULL AND length(excluded.taproot_asset_ref) > 0 + AND excluded.taproot_asset_amount IS NOT NULL AND length(excluded.taproot_asset_amount) > 0 + THEN excluded.taproot_asset_root + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND (vtxos.taproot_asset_ref IS NULL OR length(vtxos.taproot_asset_ref) = 0) + AND (vtxos.taproot_asset_amount IS NULL OR length(vtxos.taproot_asset_amount) = 0) + THEN excluded.taproot_asset_root + ELSE vtxos.taproot_asset_root + END, + taproot_asset_ref = CASE + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND excluded.taproot_asset_ref IS NOT NULL AND length(excluded.taproot_asset_ref) > 0 + AND excluded.taproot_asset_amount IS NOT NULL AND length(excluded.taproot_asset_amount) > 0 + THEN excluded.taproot_asset_ref + ELSE vtxos.taproot_asset_ref + END, + taproot_asset_amount = CASE + WHEN excluded.taproot_asset_root IS NOT NULL AND length(excluded.taproot_asset_root) > 0 + AND excluded.taproot_asset_ref IS NOT NULL AND length(excluded.taproot_asset_ref) > 0 + AND excluded.taproot_asset_amount IS NOT NULL AND length(excluded.taproot_asset_amount) > 0 + THEN excluded.taproot_asset_amount + ELSE vtxos.taproot_asset_amount + END, last_update_time = excluded.last_update_time ` @@ -585,6 +612,8 @@ type InsertVTXOParams struct { LastUpdateTime int64 ConstructionVersion int32 TaprootAssetRoot []byte + TaprootAssetRef sql.NullString + TaprootAssetAmount []byte } // VTXO queries. @@ -612,6 +641,8 @@ func (q *Queries) InsertVTXO(ctx context.Context, arg InsertVTXOParams) error { arg.LastUpdateTime, arg.ConstructionVersion, arg.TaprootAssetRoot, + arg.TaprootAssetRef, + arg.TaprootAssetAmount, ) return err } @@ -694,7 +725,7 @@ func (q *Queries) ListActiveRounds(ctx context.Context) ([]Round, error) { } const ListAllVTXOs = `-- name: ListAllVTXOs :many -SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root FROM vtxos ORDER BY creation_time DESC +SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root, taproot_asset_ref, taproot_asset_amount FROM vtxos ORDER BY creation_time DESC ` func (q *Queries) ListAllVTXOs(ctx context.Context) ([]Vtxo, error) { @@ -731,6 +762,8 @@ func (q *Queries) ListAllVTXOs(ctx context.Context) ([]Vtxo, error) { &i.ChainDepth, &i.ConstructionVersion, &i.TaprootAssetRoot, + &i.TaprootAssetRef, + &i.TaprootAssetAmount, ); err != nil { return nil, err } @@ -939,7 +972,7 @@ func (q *Queries) ListUnspentVTXOAncestryPaths(ctx context.Context) ([]VtxoAnces } const ListUnspentVTXOs = `-- name: ListUnspentVTXOs :many -SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root FROM vtxos +SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root, taproot_asset_ref, taproot_asset_amount FROM vtxos WHERE spent = FALSE AND status != 4 ORDER BY creation_time DESC @@ -980,6 +1013,8 @@ func (q *Queries) ListUnspentVTXOs(ctx context.Context) ([]Vtxo, error) { &i.ChainDepth, &i.ConstructionVersion, &i.TaprootAssetRoot, + &i.TaprootAssetRef, + &i.TaprootAssetAmount, ); err != nil { return nil, err } @@ -1086,7 +1121,7 @@ func (q *Queries) ListVTXOAncestryPathsByStatus(ctx context.Context, status int3 } const ListVTXOsByRound = `-- name: ListVTXOsByRound :many -SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root FROM vtxos WHERE round_id = $1 ORDER BY creation_time DESC +SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root, taproot_asset_ref, taproot_asset_amount FROM vtxos WHERE round_id = $1 ORDER BY creation_time DESC ` func (q *Queries) ListVTXOsByRound(ctx context.Context, roundID string) ([]Vtxo, error) { @@ -1123,6 +1158,8 @@ func (q *Queries) ListVTXOsByRound(ctx context.Context, roundID string) ([]Vtxo, &i.ChainDepth, &i.ConstructionVersion, &i.TaprootAssetRoot, + &i.TaprootAssetRef, + &i.TaprootAssetAmount, ); err != nil { return nil, err } diff --git a/db/sqlc/schemas/generated_schema.sql b/db/sqlc/schemas/generated_schema.sql index 79f9fcb45..81c9f98eb 100644 --- a/db/sqlc/schemas/generated_schema.sql +++ b/db/sqlc/schemas/generated_schema.sql @@ -55,7 +55,7 @@ CREATE TABLE activity_entries ( ); CREATE TABLE activity_events ( - event_seq BIGSERIAL PRIMARY KEY, + event_seq INTEGER PRIMARY KEY AUTOINCREMENT, canonical_id TEXT NOT NULL REFERENCES activity_entries(canonical_id), status BIGINT NOT NULL REFERENCES activity_statuses(id), @@ -626,7 +626,7 @@ CREATE INDEX idx_vtxos_status CREATE TABLE internal_keys ( -- id is the monotonically increasing surrogate key referenced by -- consumer tables' *_key_id foreign keys. - id BIGSERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY AUTOINCREMENT, -- pubkey is the 33-byte compressed public key. pubkey BLOB NOT NULL, @@ -652,7 +652,7 @@ CREATE TABLE internal_keys ( ); CREATE TABLE ledger_entries ( - entry_id BIGSERIAL PRIMARY KEY, + entry_id INTEGER PRIMARY KEY AUTOINCREMENT, debit_account TEXT NOT NULL REFERENCES accounts(account_id), @@ -798,7 +798,7 @@ CREATE TABLE oor_package_checkpoints ( CREATE TABLE oor_package_directions ( -- direction is the persisted package direction code. - direction BIGINT PRIMARY KEY NOT NULL, + direction INTEGER PRIMARY KEY NOT NULL, -- name is the stable string representation of the direction code. name TEXT NOT NULL UNIQUE @@ -902,7 +902,7 @@ CREATE TABLE oor_session_registry ( CREATE TABLE oor_vtxo_binding_link_kinds ( -- link_kind is the persisted relation code. - link_kind BIGINT PRIMARY KEY NOT NULL, + link_kind INTEGER PRIMARY KEY NOT NULL, -- name is the stable string representation of the relation code. name TEXT NOT NULL UNIQUE @@ -1009,7 +1009,7 @@ CREATE TABLE outbox_messages ( CREATE TABLE owned_receive_script_sources ( -- source is the persisted source code. - source BIGINT PRIMARY KEY NOT NULL, + source INTEGER PRIMARY KEY NOT NULL, -- name is the stable string representation of the source code. name TEXT NOT NULL UNIQUE @@ -1701,14 +1701,14 @@ CREATE TABLE vtxos ( -- zero-indexed, so the only understood value today is 0 (V1); a future, -- genuinely different construction is added additively (V2 == 1, and so -- on). NOT NULL DEFAULT 0 keeps every row a valid V1 object. - construction_version INTEGER NOT NULL DEFAULT 0, taproot_asset_root BLOB, + construction_version INTEGER NOT NULL DEFAULT 0, taproot_asset_root BLOB, taproot_asset_ref TEXT, taproot_asset_amount BLOB, PRIMARY KEY (outpoint_hash, outpoint_index), FOREIGN KEY (round_id) REFERENCES rounds(round_id) ); CREATE TABLE wallet_utxo_log ( - entry_id BIGSERIAL PRIMARY KEY, + entry_id INTEGER PRIMARY KEY AUTOINCREMENT, -- outpoint_hash is the transaction hash (32 bytes). outpoint_hash BLOB NOT NULL, diff --git a/db/sqlc/vtxo.sql.go b/db/sqlc/vtxo.sql.go index cd7c9784c..fe203da19 100644 --- a/db/sqlc/vtxo.sql.go +++ b/db/sqlc/vtxo.sql.go @@ -129,7 +129,7 @@ func (q *Queries) ListForfeitingVTXOsByRound(ctx context.Context, forfeitRoundID } const ListLiveVTXOs = `-- name: ListLiveVTXOs :many -SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root FROM vtxos +SELECT outpoint_hash, outpoint_index, round_id, amount, pk_script, expiry, policy_template, client_key_id, operator_pubkey, batch_expiry, created_height, commitment_txid, spent, status, forfeit_round_id, forfeit_tx, forfeit_txid, replaced_by_hash, replaced_by_index, creation_time, last_update_time, chain_depth, construction_version, taproot_asset_root, taproot_asset_ref, taproot_asset_amount FROM vtxos WHERE (status < 3 OR status = 7) AND spent = FALSE ORDER BY creation_time DESC ` @@ -176,6 +176,8 @@ func (q *Queries) ListLiveVTXOs(ctx context.Context) ([]Vtxo, error) { &i.ChainDepth, &i.ConstructionVersion, &i.TaprootAssetRoot, + &i.TaprootAssetRef, + &i.TaprootAssetAmount, ); err != nil { return nil, err } @@ -242,7 +244,7 @@ func (q *Queries) ListVTXOSelectionCandidatesByStatus(ctx context.Context, statu const ListVTXOsByStatus = `-- name: ListVTXOsByStatus :many -SELECT vtxos.outpoint_hash, vtxos.outpoint_index, vtxos.round_id, vtxos.amount, vtxos.pk_script, vtxos.expiry, vtxos.policy_template, vtxos.client_key_id, vtxos.operator_pubkey, vtxos.batch_expiry, vtxos.created_height, vtxos.commitment_txid, vtxos.spent, vtxos.status, vtxos.forfeit_round_id, vtxos.forfeit_tx, vtxos.forfeit_txid, vtxos.replaced_by_hash, vtxos.replaced_by_index, vtxos.creation_time, vtxos.last_update_time, vtxos.chain_depth, vtxos.construction_version, vtxos.taproot_asset_root, +SELECT vtxos.outpoint_hash, vtxos.outpoint_index, vtxos.round_id, vtxos.amount, vtxos.pk_script, vtxos.expiry, vtxos.policy_template, vtxos.client_key_id, vtxos.operator_pubkey, vtxos.batch_expiry, vtxos.created_height, vtxos.commitment_txid, vtxos.spent, vtxos.status, vtxos.forfeit_round_id, vtxos.forfeit_tx, vtxos.forfeit_txid, vtxos.replaced_by_hash, vtxos.replaced_by_index, vtxos.creation_time, vtxos.last_update_time, vtxos.chain_depth, vtxos.construction_version, vtxos.taproot_asset_root, vtxos.taproot_asset_ref, vtxos.taproot_asset_amount, rounds.commitment_txid AS settlement_txid, rounds.confirmation_height AS settlement_height, CAST(COALESCE(( @@ -320,6 +322,8 @@ func (q *Queries) ListVTXOsByStatus(ctx context.Context, status int32) ([]ListVT &i.Vtxo.ChainDepth, &i.Vtxo.ConstructionVersion, &i.Vtxo.TaprootAssetRoot, + &i.Vtxo.TaprootAssetRef, + &i.Vtxo.TaprootAssetAmount, &i.SettlementTxid, &i.SettlementHeight, &i.SettlementFeeSat, diff --git a/db/vtxo_store.go b/db/vtxo_store.go index da742f067..4f4263792 100644 --- a/db/vtxo_store.go +++ b/db/vtxo_store.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "database/sql" + "encoding/binary" "errors" "fmt" "log/slog" @@ -25,6 +26,8 @@ import ( "github.com/lightningnetwork/lnd/keychain" ) +const taprootAssetAmountSize = 8 + // VTXOPersistenceStore implements the vtxo.VTXOStore interface using the // BatchedTx pattern for transaction-safe VTXO lifecycle operations. type VTXOPersistenceStore struct { @@ -690,6 +693,11 @@ func (s *VTXOPersistenceStore) descriptorToInsertParams(ctx context.Context, if desc.TaprootAssetRoot != nil { taprootAssetRoot = desc.TaprootAssetRoot.CloneBytes() } + taprootAssetRef, taprootAssetAmount, err := + encodeTaprootAssetMetadata(desc) + if err != nil { + return InsertVTXOParams{}, err + } nowUnix := s.clock.Now().Unix() @@ -735,9 +743,86 @@ func (s *VTXOPersistenceStore) descriptorToInsertParams(ctx context.Context, // conflict. ConstructionVersion: int32(desc.ConstructionVersion), TaprootAssetRoot: taprootAssetRoot, + TaprootAssetRef: taprootAssetRef, + TaprootAssetAmount: taprootAssetAmount, }, nil } +// encodeTaprootAssetMetadata maps the optional SDK-neutral asset identity and +// amount onto nullable SQL columns. A historical root-only descriptor is +// accepted so rows written before migration 18 remain usable. New metadata is +// all-or-nothing and uses a fixed-width BLOB to preserve the complete uint64 +// range. +func encodeTaprootAssetMetadata(desc *vtxo.Descriptor) (sql.NullString, []byte, + error) { + + if desc == nil { + return sql.NullString{}, nil, fmt.Errorf("descriptor must be " + + "provided") + } + + assetRef := desc.TaprootAssetRef + assetAmount := desc.TaprootAssetAmount + if assetRef == "" && assetAmount == 0 { + return sql.NullString{}, nil, nil + } + if desc.TaprootAssetRoot == nil { + return sql.NullString{}, nil, fmt.Errorf("Taproot Asset " + + "metadata requires a commitment root") + } + if assetRef == "" || assetAmount == 0 { + return sql.NullString{}, nil, fmt.Errorf("Taproot Asset ref " + + "and amount must both be provided") + } + if len(assetRef) > vtxo.MaxTaprootAssetRefBytes { + return sql.NullString{}, nil, fmt.Errorf("Taproot Asset ref "+ + "exceeds %d bytes", vtxo.MaxTaprootAssetRefBytes) + } + + amount := make([]byte, taprootAssetAmountSize) + binary.BigEndian.PutUint64(amount, assetAmount) + + return sql.NullString{ + String: assetRef, + Valid: true, + }, amount, nil +} + +// decodeTaprootAssetMetadata restores the optional asset identity and amount. +// Empty columns represent either an ordinary Bitcoin VTXO or a historical +// root-only asset row. Any partially populated or non-canonical encoding is a +// database integrity error. +func decodeTaprootAssetMetadata(root *chainhash.Hash, ref sql.NullString, + amount []byte) (string, uint64, error) { + + if !ref.Valid && len(amount) == 0 { + return "", 0, nil + } + if root == nil { + return "", 0, fmt.Errorf("Taproot Asset metadata has no " + + "commitment root") + } + if !ref.Valid || ref.String == "" || len(amount) == 0 { + return "", 0, fmt.Errorf("incomplete Taproot Asset metadata") + } + if len(amount) != taprootAssetAmountSize { + return "", 0, fmt.Errorf("invalid Taproot Asset amount "+ + "length: %d", len(amount)) + } + if len(ref.String) > vtxo.MaxTaprootAssetRefBytes { + return "", 0, fmt.Errorf("Taproot Asset ref exceeds %d bytes", + vtxo.MaxTaprootAssetRefBytes) + } + + decoded := binary.BigEndian.Uint64(amount) + if decoded == 0 { + return "", 0, fmt.Errorf("Taproot Asset amount must be " + + "positive") + } + + return ref.String, decoded, nil +} + // rowToDescriptor converts a database VTXO row to a vtxo.Descriptor. The // caller's context is threaded through so any diagnostics emitted during // rehydrate (e.g. the expiry-drift warning) can pick up request-scoped @@ -842,28 +927,38 @@ func (s *VTXOPersistenceStore) rowToDescriptor(ctx context.Context, copy(root[:], row.TaprootAssetRoot) taprootAssetRoot = root } + taprootAssetRef, taprootAssetAmount, err := + decodeTaprootAssetMetadata( + taprootAssetRoot, row.TaprootAssetRef, + row.TaprootAssetAmount, + ) + if err != nil { + return nil, err + } if clientKey.PubKey == nil { clientKey.PubKey = derived.clientPubkey } return &vtxo.Descriptor{ - Outpoint: outpoint, - Amount: btcutil.Amount(row.Amount), - PolicyTemplate: derived.policyTemplate, - PkScript: row.PkScript, - TaprootAssetRoot: taprootAssetRoot, - ClientKey: clientKey, - OperatorKey: derived.operatorPubkey, - TapScript: derived.tapscript, - Ancestry: ancestry, - RoundID: row.RoundID, - CommitmentTxID: commitmentTxID, - BatchExpiry: row.BatchExpiry, - RelativeExpiry: derived.relativeExpiry, - ChainDepth: int(row.ChainDepth), - CreatedHeight: row.CreatedHeight, - Status: vtxo.VTXOStatus(row.Status), + Outpoint: outpoint, + Amount: btcutil.Amount(row.Amount), + PolicyTemplate: derived.policyTemplate, + PkScript: row.PkScript, + TaprootAssetRoot: taprootAssetRoot, + TaprootAssetRef: taprootAssetRef, + TaprootAssetAmount: taprootAssetAmount, + ClientKey: clientKey, + OperatorKey: derived.operatorPubkey, + TapScript: derived.tapscript, + Ancestry: ancestry, + RoundID: row.RoundID, + CommitmentTxID: commitmentTxID, + BatchExpiry: row.BatchExpiry, + RelativeExpiry: derived.relativeExpiry, + ChainDepth: int(row.ChainDepth), + CreatedHeight: row.CreatedHeight, + Status: vtxo.VTXOStatus(row.Status), ConstructionVersion: arkrpc.ConstructionVersion( row.ConstructionVersion, ), diff --git a/db/vtxo_store_test.go b/db/vtxo_store_test.go index f9b15e387..5b1985529 100644 --- a/db/vtxo_store_test.go +++ b/db/vtxo_store_test.go @@ -2,6 +2,7 @@ package db import ( "database/sql" + "encoding/binary" "testing" "github.com/btcsuite/btcd/btcec/v2" @@ -373,6 +374,8 @@ func TestListSelectionCandidatesByStatus(t *testing.T) { descAsset := createTestVTXODescriptor(t, roundID, 13) assetRoot := chainhash.Hash{0xa1, 0xb2, 0xc3} descAsset.TaprootAssetRoot = &assetRoot + descAsset.TaprootAssetRef = "asset:selection-candidate" + descAsset.TaprootAssetAmount = ^uint64(0) assetPkScript, err := descAsset.EffectivePkScript() require.NoError(t, err) descAsset.PkScript = assetPkScript @@ -404,6 +407,12 @@ func TestListSelectionCandidatesByStatus(t *testing.T) { storedAsset, err := vtxoStore.GetVTXO(ctx, descAsset.Outpoint) require.NoError(t, err) require.Equal(t, &assetRoot, storedAsset.TaprootAssetRoot) + require.Equal( + t, descAsset.TaprootAssetRef, storedAsset.TaprootAssetRef, + ) + require.Equal( + t, descAsset.TaprootAssetAmount, storedAsset.TaprootAssetAmount, + ) require.Equal(t, descAsset.PkScript, storedAsset.PkScript) // A status the projection was not asked for stays invisible. @@ -421,6 +430,248 @@ func TestListSelectionCandidatesByStatus(t *testing.T) { require.Equal(t, descB.Outpoint, candidates[0].Outpoint) } +// TestTaprootAssetMetadataCodec verifies the SQL boundary preserves the full +// uint64 asset-amount range while accepting historical root-only rows and +// rejecting partial or non-canonical metadata. +func TestTaprootAssetMetadataCodec(t *testing.T) { + t.Parallel() + + root := chainhash.HashH([]byte("asset-metadata-root")) + maxAmount := ^uint64(0) + desc := &vtxo.Descriptor{ + TaprootAssetRoot: &root, + TaprootAssetRef: "asset:max-supply", + TaprootAssetAmount: maxAmount, + } + + ref, amount, err := encodeTaprootAssetMetadata(desc) + require.NoError(t, err) + require.Equal(t, sql.NullString{ + String: desc.TaprootAssetRef, + Valid: true, + }, ref) + require.Len(t, amount, taprootAssetAmountSize) + require.Equal(t, maxAmount, binary.BigEndian.Uint64(amount)) + + decodedRef, decodedAmount, err := decodeTaprootAssetMetadata( + &root, ref, amount, + ) + require.NoError(t, err) + require.Equal(t, desc.TaprootAssetRef, decodedRef) + require.Equal(t, maxAmount, decodedAmount) + + legacyRef, legacyAmount, err := encodeTaprootAssetMetadata( + &vtxo.Descriptor{ + TaprootAssetRoot: &root, + }, + ) + require.NoError(t, err) + require.False(t, legacyRef.Valid) + require.Empty(t, legacyAmount) + + decodedRef, decodedAmount, err = decodeTaprootAssetMetadata( + &root, sql.NullString{}, nil, + ) + require.NoError(t, err) + require.Empty(t, decodedRef) + require.Zero(t, decodedAmount) + + encodeTests := []struct { + name string + desc *vtxo.Descriptor + want string + }{ + { + name: "nil descriptor", + want: "descriptor must be provided", + }, + { + name: "metadata without root", + desc: &vtxo.Descriptor{ + TaprootAssetRef: "asset:no-root", + TaprootAssetAmount: 1, + }, + want: "requires a commitment root", + }, + { + name: "reference without amount", + desc: &vtxo.Descriptor{ + TaprootAssetRoot: &root, + TaprootAssetRef: "asset:partial", + }, + want: "ref and amount must both be provided", + }, + { + name: "amount without reference", + desc: &vtxo.Descriptor{ + TaprootAssetRoot: &root, + TaprootAssetAmount: 1, + }, + want: "ref and amount must both be provided", + }, + } + for _, test := range encodeTests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + _, _, err := encodeTaprootAssetMetadata(test.desc) + require.ErrorContains(t, err, test.want) + }) + } + + canonicalAmount := make([]byte, taprootAssetAmountSize) + binary.BigEndian.PutUint64(canonicalAmount, 1) + decodeTests := []struct { + name string + root *chainhash.Hash + ref sql.NullString + amount []byte + want string + }{ + { + name: "metadata without root", + ref: sql.NullString{ + String: "asset:no-root", + Valid: true, + }, + amount: canonicalAmount, + want: "has no commitment root", + }, + { + name: "missing reference", + root: &root, + amount: canonicalAmount, + want: "incomplete Taproot Asset metadata", + }, + { + name: "empty reference", + root: &root, + ref: sql.NullString{ + Valid: true, + }, + amount: canonicalAmount, + want: "incomplete Taproot Asset metadata", + }, + { + name: "missing amount", + root: &root, + ref: sql.NullString{ + String: "asset:missing-amount", + Valid: true, + }, + want: "incomplete Taproot Asset metadata", + }, + { + name: "short amount blob", + root: &root, + ref: sql.NullString{ + String: "asset:short", + Valid: true, + }, + amount: []byte{ + 1, + }, + want: "invalid Taproot Asset amount length", + }, + { + name: "long amount blob", + root: &root, + ref: sql.NullString{ + String: "asset:long", + Valid: true, + }, + amount: make([]byte, taprootAssetAmountSize+1), + want: "invalid Taproot Asset amount length", + }, + { + name: "zero amount", + root: &root, + ref: sql.NullString{ + String: "asset:zero", + Valid: true, + }, + amount: make([]byte, taprootAssetAmountSize), + want: "amount must be positive", + }, + } + for _, test := range decodeTests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + _, _, err := decodeTaprootAssetMetadata( + test.root, test.ref, test.amount, + ) + require.ErrorContains(t, err, test.want) + }) + } +} + +// TestVTXOPersistenceStoreTaprootAssetMetadataUpsert proves a historical +// root-only row can be atomically enriched with asset identity and a full +// uint64 amount, while partial or root-only retries cannot split or erase the +// persisted metadata tuple. +func TestVTXOPersistenceStoreTaprootAssetMetadataUpsert(t *testing.T) { + t.Parallel() + + vtxoStore, roundStore, _ := newVTXOStoreForTest(t) + ctx := t.Context() + + roundID := testRoundIDDB("test-asset-metadata-upsert") + testRound := createTestRound(t, roundID) + state := &round.InputSigSentState{ + RoundID: testRound.RoundID, + ClientTrees: make(map[round.SignerKey]*tree.Tree), + } + require.NoError(t, roundStore.CommitState(ctx, testRound, state)) + + root := chainhash.HashH([]byte("asset-upsert-root")) + desc := createTestVTXODescriptor(t, roundID, 31) + desc.TaprootAssetRoot = &root + pkScript, err := desc.EffectivePkScript() + require.NoError(t, err) + desc.PkScript = pkScript + require.NoError(t, vtxoStore.SaveVTXO(ctx, desc)) + + legacy, err := vtxoStore.GetVTXO(ctx, desc.Outpoint) + require.NoError(t, err) + require.Equal(t, &root, legacy.TaprootAssetRoot) + require.Empty(t, legacy.TaprootAssetRef) + require.Zero(t, legacy.TaprootAssetAmount) + + const assetRef = "asset:upsert" + maxAmount := ^uint64(0) + desc.TaprootAssetRef = assetRef + desc.TaprootAssetAmount = maxAmount + require.NoError(t, vtxoStore.SaveVTXO(ctx, desc)) + + assertComplete := func() { + t.Helper() + + stored, err := vtxoStore.GetVTXO(ctx, desc.Outpoint) + require.NoError(t, err) + require.Equal(t, &root, stored.TaprootAssetRoot) + require.Equal(t, assetRef, stored.TaprootAssetRef) + require.Equal(t, maxAmount, stored.TaprootAssetAmount) + } + assertComplete() + + // A replay from a pre-migration daemon carries only the root. The + // upsert must preserve the richer tuple already stored. + desc.TaprootAssetRef = "" + desc.TaprootAssetAmount = 0 + require.NoError(t, vtxoStore.SaveVTXO(ctx, desc)) + assertComplete() + + // A partial update is rejected before the SQL upsert and leaves the + // complete tuple intact. + desc.TaprootAssetRef = "asset:partial" + err = vtxoStore.SaveVTXO(ctx, desc) + require.ErrorContains(t, err, "ref and amount must both be provided") + assertComplete() +} + // TestListVTXOsLightSkipsAncestry exercises the light listing variants the // ListVTXOs RPC runs on: the descriptors must match the full listing in // every field except Ancestry, which the light path never loads. diff --git a/docs/taproot-assets-asset-state-execplan.md b/docs/taproot-assets-asset-state-execplan.md index 02ee7a756..a5bc96999 100644 --- a/docs/taproot-assets-asset-state-execplan.md +++ b/docs/taproot-assets-asset-state-execplan.md @@ -44,17 +44,21 @@ simulated restart returns identical proof-path and witness bytes. - [x] (2026-07-21 17:54Z) Created `feat/taproot-assets-asset-state` above `feat/taproot-assets-carrier-selection` and wrote this living plan. -- [ ] Add SDK-neutral asset identity and amount to descriptor persistence and +- [x] (2026-07-21 18:24Z) Added SDK-neutral asset identity and amount to + descriptor persistence and the public VTXO projection, including a full-`uint64` database encoding. -- [ ] Propagate asset metadata through onboarding, recipient wire messages, +- [x] (2026-07-21 18:24Z) Propagated asset metadata through onboarding, + operator signing descriptors, recipient wire messages, OOR snapshots and actor messages, and incoming VTXO materialization. -- [ ] Generalize the v0 sealed asset container and prepared-submit validation +- [x] (2026-07-21 18:24Z) Generalized the v0 sealed asset container and + prepared-submit validation for positional Bitcoin-only checkpoint slots and Bitcoin-only recipients. -- [ ] Add exact created-output package lookup and the tapassets proof-source +- [x] (2026-07-21 18:24Z) Added exact created-output package lookup and the + tapassets proof-source resolver/projection. -- [ ] Regenerate SQL/protobuf output, add comprehensive compatibility and - restart tests, and complete formatting, race, unit, build, lint, and commit - validation. +- [x] (2026-07-21 18:56Z) Regenerated SQL/protobuf output, added + compatibility and restart tests, and completed formatting, focused and full + unit tests, focused race tests, build, and changed-file lint validation. ## Surprises & Discoveries @@ -76,6 +80,24 @@ simulated restart returns identical proof-path and witness bytes. outpoint/script-key search. The upstream package additionally exposes stable logical IDs, packet and virtual indices, anchor indices, proof-source kind and bytes, script mode, and the exact OP_TRUE witness. +- Observation: the Docker daemon was unavailable, so the repository wrappers + could not generate SQL or protobuf output. The same pinned tools were run + locally: sqlc 1.29.0, protoc 3.21.12, protoc-gen-go 1.36.11, + protoc-gen-go-grpc 1.5.1, and grpc-gateway 2.29.0. The merged SQL schema and + all protobuf packages were regenerated successfully. +- Observation: generic seed recovery still queries the indexer with the + ordinary receive pkScript. An asset-bearing VTXO instead commits to the + composed Ark-policy and asset root, so metadata hydration alone cannot make + seed recovery discover those scripts. Recovery needs an indexer query by + owner identity or another asset-aware inventory primitive and remains an + explicit follow-up. +- Observation: an incoming recipient event can locally bind its root to the + announced P2TR script and can enforce complete, bounded ref/amount metadata, + but the SDK-neutral OOR package layer cannot prove that the opaque ref and + amount correspond to that root. For this PoC, the operator is the + authoritative validator of the sealed Ark package before publishing these + fields. A later trust-minimized receiver path can inject the tapassets + projection at the wallet boundary. ## Decision Log @@ -115,12 +137,26 @@ simulated restart returns identical proof-path and witness bytes. mappings once and return opaque proof bytes, plain strings and integers, `wire.OutPoint`, and cloned witness stacks. Date/Author: 2026-07-21 / Codex. +- Decision: carry canonical asset reference and amount on both recipient + outputs and operator signing descriptors. + Rationale: Lumos must bind the sealed package to the exact consumed and + created states; root-only signing metadata would leave identity and quantity + as unauthenticated hints. The client therefore sources these fields from the + validated package-backed descriptor and preserves them through every durable + retry boundary. + Date/Author: 2026-07-21 / Codex. ## Outcomes & Retrospective -Implementation is not complete yet. The current branch contains only this -plan. Update this section after each milestone with the exact behavior, test -evidence, compatibility consequences, and any remaining live integration gap. +The implementation now persists full-width asset quantities separately from +carrier sats, carries canonical SDK-neutral metadata through onboarding, +operator, recipient, actor, snapshot, and incoming-materialization boundaries, +accepts mixed Bitcoin/asset checkpoint graphs in the v0 positional package, +and reconstructs a bounded compact proof path plus OP_TRUE witness from the +exact created-output package. Historical root-only rows/messages and +all-nonempty v0 packages remain readable. Formatting, focused and full unit +tests, focused race tests, build, and changed-file lint all pass. The live +Lumos cross-repository test and asset-aware seed recovery remain follow-ups. ## Context and Orientation diff --git a/lib/tx/oor/asset_transfer.go b/lib/tx/oor/asset_transfer.go index 09e6d25b4..df7f99ea4 100644 --- a/lib/tx/oor/asset_transfer.go +++ b/lib/tx/oor/asset_transfer.go @@ -61,7 +61,9 @@ type TaprootAssetTransfer struct { // Version identifies the container schema. Version uint16 - // CheckpointPackages contains one sealed package per checkpoint edge. + // CheckpointPackages contains one positional slot per checkpoint edge. + // A non-empty slot is the sealed package for an asset-bearing + // checkpoint; an empty slot marks an ordinary Bitcoin-only checkpoint. CheckpointPackages [][]byte // ArkPackage is the sealed package for the final Ark edge. @@ -97,9 +99,16 @@ func (t *TaprootAssetTransfer) Validate(expectedCheckpoints int) error { len(t.CheckpointPackages), expectedCheckpoints) } - var total uint64 + var ( + total uint64 + assetPackages int + ) for i := range t.CheckpointPackages { total += uint64(len(t.CheckpointPackages[i])) + if len(t.CheckpointPackages[i]) == 0 { + continue + } + assetPackages++ if err := validateTaprootAssetPackage( fmt.Sprintf("checkpoint package %d", i), t.CheckpointPackages[i], @@ -107,6 +116,10 @@ func (t *TaprootAssetTransfer) Validate(expectedCheckpoints int) error { return err } } + if assetPackages == 0 { + return fmt.Errorf("%w: at least one asset-bearing checkpoint "+ + "package is required", ErrTaprootAssetTransferInvalid) + } total += uint64(len(t.ArkPackage)) if err := validateTaprootAssetPackage( "Ark package", t.ArkPackage, @@ -160,7 +173,7 @@ func (t *TaprootAssetTransfer) MarshalBinary() ([]byte, error) { return nil, err } for i := range t.CheckpointPackages { - if err := writeTaprootAssetPackage( + if err := writeTaprootAssetCheckpointSlot( &body, t.CheckpointPackages[i], ); err != nil { return nil, err @@ -243,7 +256,7 @@ func (t *TaprootAssetTransfer) UnmarshalBinary(encoded []byte) error { CheckpointPackages: make([][]byte, count), } for i := range decoded.CheckpointPackages { - pkg, err := readTaprootAssetPackage(reader) + pkg, err := readTaprootAssetCheckpointSlot(reader) if err != nil { return fmt.Errorf("%w: checkpoint package %d: %w", ErrTaprootAssetTransferInvalid, i, err) @@ -300,6 +313,29 @@ func writeTaprootAssetPackage(w io.Writer, pkg []byte) error { return err } +func writeTaprootAssetCheckpointSlot(w io.Writer, pkg []byte) error { + if len(pkg) > MaxTaprootAssetPackageBytes { + return fmt.Errorf("%w: package size %d exceeds %d", + ErrTaprootAssetTransferInvalid, len(pkg), + MaxTaprootAssetPackageBytes) + } + if err := binary.Write( + w, binary.BigEndian, + uint32( + len(pkg), + ), + ); err != nil { + return err + } + if len(pkg) == 0 { + return nil + } + + _, err := w.Write(pkg) + + return err +} + func readTaprootAssetPackage(r *bytes.Reader) ([]byte, error) { var length uint32 if err := binary.Read(r, binary.BigEndian, &length); err != nil { @@ -317,3 +353,24 @@ func readTaprootAssetPackage(r *bytes.Reader) ([]byte, error) { return pkg, err } + +func readTaprootAssetCheckpointSlot(r *bytes.Reader) ([]byte, error) { + var length uint32 + if err := binary.Read(r, binary.BigEndian, &length); err != nil { + return nil, err + } + if length > MaxTaprootAssetPackageBytes { + return nil, fmt.Errorf("invalid package size %d", length) + } + if length == 0 { + return nil, nil + } + if uint64(length) > uint64(r.Len()) { + return nil, io.ErrUnexpectedEOF + } + + pkg := make([]byte, length) + _, err := io.ReadFull(r, pkg) + + return pkg, err +} diff --git a/lib/tx/oor/asset_transfer_test.go b/lib/tx/oor/asset_transfer_test.go index 43b783123..ee8372f68 100644 --- a/lib/tx/oor/asset_transfer_test.go +++ b/lib/tx/oor/asset_transfer_test.go @@ -1,6 +1,7 @@ package oor import ( + "crypto/sha256" "errors" "testing" @@ -27,6 +28,9 @@ func TestTaprootAssetTransferRoundTrip(t *testing.T) { require.NoError(t, decoded.UnmarshalBinary(encoded)) require.Equal(t, original, &decoded) require.NoError(t, decoded.Validate(2)) + reencoded, err := decoded.MarshalBinary() + require.NoError(t, err) + require.Equal(t, encoded, reencoded) clone := decoded.Clone() clone.CheckpointPackages[0][0] ^= 1 @@ -37,6 +41,32 @@ func TestTaprootAssetTransferRoundTrip(t *testing.T) { require.NotEqual(t, clone.ArkPackage, decoded.ArkPackage) } +// TestTaprootAssetTransferMixedSlots pins the v0 positional encoding used by +// one asset-bearing input alongside ordinary Bitcoin-only inputs. +func TestTaprootAssetTransferMixedSlots(t *testing.T) { + t.Parallel() + + original := &TaprootAssetTransfer{ + Version: TaprootAssetTransferVersion, + CheckpointPackages: [][]byte{ + []byte("asset-0"), nil, []byte("asset-2"), + }, + ArkPackage: []byte("ark"), + } + require.NoError(t, original.Validate(3)) + encoded, err := original.MarshalBinary() + require.NoError(t, err) + + var decoded TaprootAssetTransfer + require.NoError(t, decoded.UnmarshalBinary(encoded)) + require.Equal(t, original, &decoded) + require.Nil(t, decoded.CheckpointPackages[1]) + + reencoded, err := decoded.MarshalBinary() + require.NoError(t, err) + require.Equal(t, encoded, reencoded) +} + func TestTaprootAssetTransferRejectsInvalidContainers(t *testing.T) { t.Parallel() @@ -91,7 +121,7 @@ func TestTaprootAssetTransferRejectsInvalidContainers(t *testing.T) { target: ErrTaprootAssetTransferInvalid, }, { - name: "empty checkpoint", + name: "all checkpoints empty", value: &TaprootAssetTransfer{ Version: TaprootAssetTransferVersion, CheckpointPackages: [][]byte{ @@ -140,4 +170,16 @@ func TestTaprootAssetTransferRejectsInvalidContainers(t *testing.T) { t, errors.Is(err, ErrTaprootAssetTransferInvalid) || errors.Is(err, ErrTaprootAssetTransferVersion), ) + + // Append a body byte and recompute the checksum so parsing reaches the + // explicit trailing-byte check instead of stopping at checksum failure. + body := append( + []byte(nil), encoded[:len(encoded)-sha256.Size]..., + ) + body = append(body, 0xff) + checksum := sha256.Sum256(body) + trailing := append([]byte(nil), body...) + trailing = append(trailing, checksum[:]...) + err = decoded.UnmarshalBinary(trailing) + require.ErrorContains(t, err, "trailing bytes") } diff --git a/lib/tx/oor/build.go b/lib/tx/oor/build.go index 246abf34c..701883555 100644 --- a/lib/tx/oor/build.go +++ b/lib/tx/oor/build.go @@ -13,6 +13,13 @@ import ( "github.com/lightninglabs/wavelength/lib/arkscript" "github.com/lightninglabs/wavelength/lib/tx/arktx" "github.com/lightninglabs/wavelength/lib/tx/checkpoint" + "github.com/lightninglabs/wavelength/vtxo" +) + +const ( + // MaxTaprootAssetRefBytes bounds the opaque tap-sdk asset identifier on + // every SDK-neutral recipient and persistence boundary. + MaxTaprootAssetRefBytes = vtxo.MaxTaprootAssetRefBytes ) // CheckpointInput describes the VTXO input being transformed into a checkpoint @@ -88,12 +95,23 @@ type RecipientOutput struct { // operators reconstruct the composed control blocks without importing // taproot-assets implementation types. TaprootAssetRoot *chainhash.Hash + + // TaprootAssetRef is the opaque SDK-level identity of the asset carried + // by this output. + TaprootAssetRef string + + // TaprootAssetAmount is the number of asset units carried by this + // output. Value remains the separate Bitcoin carrier amount. + TaprootAssetAmount uint64 } // ValidateTaprootAssetCommitment proves that an asset-bearing recipient // output commits to both its semantic Ark policy and its declared Taproot // Asset root. Bitcoin-only outputs are unchanged. func (o RecipientOutput) ValidateTaprootAssetCommitment() error { + if err := o.ValidateTaprootAssetMetadata(); err != nil { + return err + } if o.TaprootAssetRoot == nil { return nil } @@ -131,6 +149,34 @@ func (o RecipientOutput) ValidateTaprootAssetCommitment() error { return nil } +// ValidateTaprootAssetMetadata checks that SDK-neutral asset identity and +// quantity are either absent or complete. A root-only output is accepted for +// compatibility with v0 packages created before identity and amount were +// propagated. +func (o RecipientOutput) ValidateTaprootAssetMetadata() error { + if o.TaprootAssetRoot == nil { + if o.TaprootAssetRef != "" || o.TaprootAssetAmount != 0 { + return fmt.Errorf("recipient asset metadata requires " + + "a commitment root") + } + + return nil + } + if o.TaprootAssetRef == "" && o.TaprootAssetAmount == 0 { + return nil + } + if o.TaprootAssetRef == "" || o.TaprootAssetAmount == 0 { + return fmt.Errorf("recipient asset ref and amount must both " + + "be provided") + } + if len(o.TaprootAssetRef) > MaxTaprootAssetRefBytes { + return fmt.Errorf("recipient asset ref exceeds %d bytes", + MaxTaprootAssetRefBytes) + } + + return nil +} + // CanonicalRecipientOutputs returns a BIP69-style stable copy of recipients in // the same order used by BuildArkPSBT. func CanonicalRecipientOutputs(recipients []RecipientOutput) []RecipientOutput { diff --git a/oor/actor_durable_message.go b/oor/actor_durable_message.go index 5f42f940e..376633512 100644 --- a/oor/actor_durable_message.go +++ b/oor/actor_durable_message.go @@ -16,6 +16,7 @@ import ( "github.com/btcsuite/btcd/wire/v2" clientdb "github.com/lightninglabs/wavelength/db" "github.com/lightninglabs/wavelength/lib/tree" + oortx "github.com/lightninglabs/wavelength/lib/tx/oor" "github.com/lightninglabs/wavelength/lib/tx/psbtutil" "github.com/lightninglabs/wavelength/vtxo" "github.com/lightningnetwork/lnd/tlv" @@ -128,14 +129,18 @@ const ( transferInputRequiredLockTimeRecordType tlv.Type = 16 transferInputExternalSignaturesRecordType tlv.Type = 17 transferInputTaprootAssetRootRecordType tlv.Type = 18 + transferInputTaprootAssetRefRecordType tlv.Type = 19 + transferInputTaprootAssetAmountRecordType tlv.Type = 20 ) const ( - recipientPkScriptRecordType tlv.Type = 1 - recipientValueSatRecordType tlv.Type = 2 - recipientVTXOPolicyRecordType tlv.Type = 3 - recipientTaprootAssetRootType tlv.Type = 4 - recipientOutputIndexRecordType tlv.Type = 5 + recipientPkScriptRecordType tlv.Type = 1 + recipientValueSatRecordType tlv.Type = 2 + recipientVTXOPolicyRecordType tlv.Type = 3 + recipientTaprootAssetRootType tlv.Type = 4 + recipientOutputIndexRecordType tlv.Type = 5 + recipientTaprootAssetRefType tlv.Type = 6 + recipientTaprootAssetAmountType tlv.Type = 7 ) const ( @@ -164,6 +169,8 @@ type recipientPayload struct { ValueSat int64 VTXOPolicyTemplate []byte TaprootAssetRoot *chainhash.Hash + TaprootAssetRef string + TaprootAssetAmount uint64 } type incomingRecipientPayload struct { @@ -172,6 +179,8 @@ type incomingRecipientPayload struct { ValueSat int64 VTXOPolicyTemplate []byte TaprootAssetRoot *chainhash.Hash + TaprootAssetRef string + TaprootAssetAmount uint64 } func encodeStartTransferPayload(payload startTransferPayload) ([]byte, error) { @@ -832,6 +841,12 @@ func decodeOptionalPubKey(raw []byte, name string) (*btcec.PublicKey, error) { } func encodeRecipientPayload(payload recipientPayload) ([]byte, error) { + if err := validateDurableAssetMetadata( + payload.TaprootAssetRoot, payload.TaprootAssetRef, + payload.TaprootAssetAmount, + ); err != nil { + return nil, fmt.Errorf("recipient asset metadata: %w", err) + } pkScript := payload.PkScript if payload.ValueSat < 0 { return nil, fmt.Errorf("recipient value must be non-negative") @@ -854,6 +869,22 @@ func encodeRecipientPayload(payload recipientPayload) ([]byte, error) { ), ) } + if payload.TaprootAssetRef != "" { + assetRef := []byte(payload.TaprootAssetRef) + records = append( + records, tlv.MakePrimitiveRecord( + recipientTaprootAssetRefType, &assetRef, + ), + ) + } + if payload.TaprootAssetAmount != 0 { + assetAmount := payload.TaprootAssetAmount + records = append( + records, tlv.MakePrimitiveRecord( + recipientTaprootAssetAmountType, &assetAmount, + ), + ) + } stream, err := tlv.NewStream(records...) if err != nil { @@ -874,6 +905,8 @@ func decodeRecipientPayload(raw []byte) (recipientPayload, error) { valueSat uint64 vtxoPolicyTemplate []byte assetRootRaw []byte + assetRefRaw []byte + assetAmount uint64 ) records := []tlv.Record{ @@ -885,6 +918,12 @@ func decodeRecipientPayload(raw []byte) (recipientPayload, error) { tlv.MakePrimitiveRecord( recipientTaprootAssetRootType, &assetRootRaw, ), + tlv.MakePrimitiveRecord( + recipientTaprootAssetRefType, &assetRefRaw, + ), + tlv.MakePrimitiveRecord( + recipientTaprootAssetAmountType, &assetAmount, + ), } stream, err := tlv.NewStream(records...) @@ -908,6 +947,8 @@ func decodeRecipientPayload(raw []byte) (recipientPayload, error) { PkScript: pkScript, ValueSat: decodedValueSat, VTXOPolicyTemplate: vtxoPolicyTemplate, + TaprootAssetRef: string(assetRefRaw), + TaprootAssetAmount: assetAmount, } if len(assetRootRaw) > 0 { assetRoot, err := chainhash.NewHash(assetRootRaw) @@ -918,6 +959,13 @@ func decodeRecipientPayload(raw []byte) (recipientPayload, error) { result.TaprootAssetRoot = assetRoot } + if err := validateDurableAssetMetadata( + result.TaprootAssetRoot, result.TaprootAssetRef, + result.TaprootAssetAmount, + ); err != nil { + return recipientPayload{}, fmt.Errorf("recipient asset "+ + "metadata: %w", err) + } return result, nil } @@ -938,6 +986,10 @@ func encodeIncomingRecipients(recipients []ArkRecipientOutput) ([]byte, error) { ), TaprootAssetRoot: recipients[i]. TaprootAssetRoot, + TaprootAssetRef: recipients[i]. + TaprootAssetRef, + TaprootAssetAmount: recipients[i]. + TaprootAssetAmount, }, ) if err != nil { @@ -978,7 +1030,9 @@ func decodeIncomingRecipientsWithLimits(raw []byte, VTXOPolicyTemplate: append( []byte(nil), payload.VTXOPolicyTemplate..., ), - TaprootAssetRoot: payload.TaprootAssetRoot, + TaprootAssetRoot: payload.TaprootAssetRoot, + TaprootAssetRef: payload.TaprootAssetRef, + TaprootAssetAmount: payload.TaprootAssetAmount, }) } @@ -988,6 +1042,14 @@ func decodeIncomingRecipientsWithLimits(raw []byte, func encodeIncomingRecipientPayload(payload incomingRecipientPayload) ([]byte, error) { + if err := validateDurableAssetMetadata( + payload.TaprootAssetRoot, payload.TaprootAssetRef, + payload.TaprootAssetAmount, + ); err != nil { + return nil, fmt.Errorf("incoming recipient asset metadata: %w", + err) + } + pkScript := payload.PkScript if payload.ValueSat < 0 { return nil, fmt.Errorf("incoming recipient value must be " + @@ -999,6 +1061,8 @@ func encodeIncomingRecipientPayload(payload incomingRecipientPayload) ([]byte, if payload.TaprootAssetRoot != nil { taprootAssetRoot = payload.TaprootAssetRoot.CloneBytes() } + taprootAssetRef := []byte(payload.TaprootAssetRef) + taprootAssetAmount := payload.TaprootAssetAmount records := []tlv.Record{ tlv.MakePrimitiveRecord( @@ -1017,6 +1081,12 @@ func encodeIncomingRecipientPayload(payload incomingRecipientPayload) ([]byte, tlv.MakePrimitiveRecord( recipientOutputIndexRecordType, &outputIndex, ), + tlv.MakePrimitiveRecord( + recipientTaprootAssetRefType, &taprootAssetRef, + ), + tlv.MakePrimitiveRecord( + recipientTaprootAssetAmountType, &taprootAssetAmount, + ), } stream, err := tlv.NewStream(records...) @@ -1041,6 +1111,8 @@ func decodeIncomingRecipientPayload(raw []byte) (incomingRecipientPayload, vtxoPolicyTemplate []byte outputIndex uint64 taprootAssetRoot []byte + taprootAssetRef []byte + taprootAssetAmount uint64 ) records := []tlv.Record{ @@ -1055,6 +1127,12 @@ func decodeIncomingRecipientPayload(raw []byte) (incomingRecipientPayload, tlv.MakePrimitiveRecord( recipientOutputIndexRecordType, &outputIndex, ), + tlv.MakePrimitiveRecord( + recipientTaprootAssetRefType, &taprootAssetRef, + ), + tlv.MakePrimitiveRecord( + recipientTaprootAssetAmountType, &taprootAssetAmount, + ), } stream, err := tlv.NewStream(records...) @@ -1086,6 +1164,8 @@ func decodeIncomingRecipientPayload(raw []byte) (incomingRecipientPayload, PkScript: pkScript, ValueSat: decodedValueSat, VTXOPolicyTemplate: vtxoPolicyTemplate, + TaprootAssetRef: string(taprootAssetRef), + TaprootAssetAmount: taprootAssetAmount, } if len(taprootAssetRoot) > 0 { root, err := chainhash.NewHash(taprootAssetRoot) @@ -1096,10 +1176,27 @@ func decodeIncomingRecipientPayload(raw []byte) (incomingRecipientPayload, } result.TaprootAssetRoot = root } + if err := validateDurableAssetMetadata( + result.TaprootAssetRoot, result.TaprootAssetRef, + result.TaprootAssetAmount, + ); err != nil { + return incomingRecipientPayload{}, fmt.Errorf("incoming "+ + "recipient asset metadata: %w", err) + } return result, nil } +func validateDurableAssetMetadata(root *chainhash.Hash, ref string, + amount uint64) error { + + return (oortx.RecipientOutput{ + TaprootAssetRoot: root, + TaprootAssetRef: ref, + TaprootAssetAmount: amount, + }).ValidateTaprootAssetMetadata() +} + func encodeTransferInputSnapshots(inputs []*TransferInputSnapshot) ([]byte, error) { @@ -1144,6 +1241,12 @@ func encodeTransferInputSnapshot(input *TransferInputSnapshot) ([]byte, error) { return nil, fmt.Errorf("transfer input snapshot must be " + "provided") } + if err := validateDurableAssetMetadata( + input.TaprootAssetRoot, input.TaprootAssetRef, + input.TaprootAssetAmount, + ); err != nil { + return nil, fmt.Errorf("transfer input asset metadata: %w", err) + } outpoint := outPointBytes(input.Outpoint) amountSat := uint64(input.AmountSat) @@ -1293,6 +1396,24 @@ func encodeTransferInputSnapshot(input *TransferInputSnapshot) ([]byte, error) { ), ) } + if input.TaprootAssetRef != "" { + assetRef := []byte(input.TaprootAssetRef) + records = append( + records, tlv.MakePrimitiveRecord( + transferInputTaprootAssetRefRecordType, + &assetRef, + ), + ) + } + if input.TaprootAssetAmount != 0 { + assetAmount := input.TaprootAssetAmount + records = append( + records, tlv.MakePrimitiveRecord( + transferInputTaprootAssetAmountRecordType, + &assetAmount, + ), + ) + } stream, err := tlv.NewStream(records...) if err != nil { @@ -1327,6 +1448,8 @@ func decodeTransferInputSnapshot(raw []byte) (*TransferInputSnapshot, error) { requiredSequence uint32 requiredLockTime uint32 assetRootRaw []byte + assetRefRaw []byte + assetAmount uint64 ) records := []tlv.Record{ @@ -1390,6 +1513,12 @@ func decodeTransferInputSnapshot(raw []byte) (*TransferInputSnapshot, error) { tlv.MakePrimitiveRecord( transferInputTaprootAssetRootRecordType, &assetRootRaw, ), + tlv.MakePrimitiveRecord( + transferInputTaprootAssetRefRecordType, &assetRefRaw, + ), + tlv.MakePrimitiveRecord( + transferInputTaprootAssetAmountRecordType, &assetAmount, + ), } stream, err := tlv.NewStream(records...) @@ -1435,6 +1564,8 @@ func decodeTransferInputSnapshot(raw []byte) (*TransferInputSnapshot, error) { SpendControlBlock: controlBlock, RequiredSequence: requiredSequence, RequiredLockTime: requiredLockTime, + TaprootAssetRef: string(assetRefRaw), + TaprootAssetAmount: assetAmount, } if len(condBlob) > 0 { @@ -1464,6 +1595,12 @@ func decodeTransferInputSnapshot(raw []byte) (*TransferInputSnapshot, error) { snap.TaprootAssetRoot = assetRoot } + if err := validateDurableAssetMetadata( + snap.TaprootAssetRoot, snap.TaprootAssetRef, + snap.TaprootAssetAmount, + ); err != nil { + return nil, fmt.Errorf("transfer input asset metadata: %w", err) + } return snap, nil } diff --git a/oor/actor_durable_message_test.go b/oor/actor_durable_message_test.go index 84e92bd05..c6d0feda4 100644 --- a/oor/actor_durable_message_test.go +++ b/oor/actor_durable_message_test.go @@ -62,6 +62,11 @@ func TestStartTransferPayloadTLVRoundTrip(t *testing.T) { 0x20, }, ValueSat: 321, + TaprootAssetRoot: &chainhash.Hash{ + 0xaa, + }, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, }, }, IdempotencyKey: "funding-key-1", @@ -409,6 +414,8 @@ func TestDriveEventRequestRoundTripIncomingTransferEvent(t *testing.T) { sessionID := SessionID(arkPSBT.UnsignedTx.TxHash()) assetRoot := chainhash.Hash{0x31, 0x32, 0x33} recipients[0].TaprootAssetRoot = &assetRoot + recipients[0].TaprootAssetRef = "asset-id:010203" + recipients[0].TaprootAssetAmount = 21 assetTransfer := &oortx.TaprootAssetTransfer{ Version: oortx.TaprootAssetTransferVersion, CheckpointPackages: [][]byte{ @@ -447,6 +454,12 @@ func TestDriveEventRequestRoundTripIncomingTransferEvent(t *testing.T) { require.Len(t, incomingEvt.Recipients, 1) require.Equal(t, &assetRoot, incomingEvt.Recipients[0].TaprootAssetRoot) + require.Equal( + t, "asset-id:010203", incomingEvt.Recipients[0].TaprootAssetRef, + ) + require.Equal( + t, uint64(21), incomingEvt.Recipients[0].TaprootAssetAmount, + ) require.Equal(t, assetTransfer, incomingEvt.TaprootAssetTransfer) } diff --git a/oor/actor_messages.go b/oor/actor_messages.go index cc41fdd91..289728b45 100644 --- a/oor/actor_messages.go +++ b/oor/actor_messages.go @@ -161,6 +161,10 @@ func (m *StartTransferRequest) Encode(w io.Writer) error { VTXOPolicyTemplate, TaprootAssetRoot: m.Recipients[i]. TaprootAssetRoot, + TaprootAssetRef: m.Recipients[i]. + TaprootAssetRef, + TaprootAssetAmount: m.Recipients[i]. + TaprootAssetAmount, }, ) } @@ -247,7 +251,9 @@ func (m *StartTransferRequest) Decode(r io.Reader) error { Value: btcutil.Amount(recipient.ValueSat), VTXOPolicyTemplate: recipient. VTXOPolicyTemplate, - TaprootAssetRoot: recipient.TaprootAssetRoot, + TaprootAssetRoot: recipient.TaprootAssetRoot, + TaprootAssetRef: recipient.TaprootAssetRef, + TaprootAssetAmount: recipient.TaprootAssetAmount, }) } diff --git a/oor/ark_recipients.go b/oor/ark_recipients.go index 29c91ae08..2e36975e6 100644 --- a/oor/ark_recipients.go +++ b/oor/ark_recipients.go @@ -27,6 +27,14 @@ type ArkRecipientOutput struct { // TaprootAssetRoot is the optional root of the Taproot Asset // commitment composed beside VTXOPolicyTemplate in PkScript. TaprootAssetRoot *chainhash.Hash + + // TaprootAssetRef is the opaque SDK-level identity carried by the + // output. + TaprootAssetRef string + + // TaprootAssetAmount is the number of asset units carried by the + // output. Value remains the Bitcoin carrier amount. + TaprootAssetAmount uint64 } // ExtractArkRecipients returns the non-anchor outputs from a canonical Ark @@ -89,6 +97,8 @@ func CloneArkRecipients(recipients []ArkRecipientOutput) []ArkRecipientOutput { []byte(nil), recipients[i].VTXOPolicyTemplate..., ), + TaprootAssetRef: recipients[i].TaprootAssetRef, + TaprootAssetAmount: recipients[i].TaprootAssetAmount, } if recipients[i].TaprootAssetRoot != nil { root := *recipients[i].TaprootAssetRoot diff --git a/oor/incoming_adapter.go b/oor/incoming_adapter.go index 723d9ffca..429e934f4 100644 --- a/oor/incoming_adapter.go +++ b/oor/incoming_adapter.go @@ -244,6 +244,9 @@ func incomingRecipientsFromEvent(ark *psbt.Packet, []byte(nil), evt.GetVtxoPolicyTemplate()..., ) + recipients[i].TaprootAssetRef = evt.GetTaprootAssetRef() + recipients[i].TaprootAssetAmount = + evt.GetTaprootAssetAmount() assetRootRaw := evt.GetTaprootAssetRoot() if len(assetRootRaw) > 0 { assetRoot, err := chainhash.NewHash(assetRootRaw) @@ -253,18 +256,21 @@ func incomingRecipientsFromEvent(ark *psbt.Packet, } recipients[i].TaprootAssetRoot = assetRoot - assetRecipient := oortx.RecipientOutput{ - Value: recipients[i].Value, - PkScript: recipients[i].PkScript, - VTXOPolicyTemplate: recipients[i]. - VTXOPolicyTemplate, - TaprootAssetRoot: assetRoot, - } - err = assetRecipient.ValidateTaprootAssetCommitment() - if err != nil { - return nil, fmt.Errorf("validate recipient "+ - "Taproot Asset root: %w", err) - } + } + + assetRecipient := oortx.RecipientOutput{ + Value: recipients[i].Value, + PkScript: recipients[i].PkScript, + VTXOPolicyTemplate: recipients[i]. + VTXOPolicyTemplate, + TaprootAssetRoot: recipients[i].TaprootAssetRoot, + TaprootAssetRef: recipients[i].TaprootAssetRef, + TaprootAssetAmount: recipients[i].TaprootAssetAmount, + } + err = assetRecipient.ValidateTaprootAssetCommitment() + if err != nil { + return nil, fmt.Errorf("validate recipient Taproot "+ + "Asset metadata: %w", err) } return recipients, nil diff --git a/oor/incoming_adapter_test.go b/oor/incoming_adapter_test.go index 9ff211bc9..bc4776040 100644 --- a/oor/incoming_adapter_test.go +++ b/oor/incoming_adapter_test.go @@ -6,6 +6,7 @@ import ( "github.com/btcsuite/btcd/chainhash/v2" "github.com/lightninglabs/wavelength/arkrpc" "github.com/lightninglabs/wavelength/lib/arkscript" + oortx "github.com/lightninglabs/wavelength/lib/tx/oor" "github.com/lightninglabs/wavelength/vtxo" "github.com/stretchr/testify/require" ) @@ -62,14 +63,32 @@ func TestIncomingRecipientsFromEventBindsTaprootAssetRoot(t *testing.T) { Value: uint64(recipients[0].Value), VtxoPolicyTemplate: template, TaprootAssetRoot: assetRoot[:], + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, } decoded, err := incomingRecipientsFromEvent(arkPSBT, evt) require.NoError(t, err) require.Equal(t, &assetRoot, decoded[0].TaprootAssetRoot) + require.Equal(t, "asset-id:010203", decoded[0].TaprootAssetRef) + require.Equal(t, uint64(21), decoded[0].TaprootAssetAmount) wrongRoot := chainhash.Hash{0xff} evt.TaprootAssetRoot = wrongRoot[:] _, err = incomingRecipientsFromEvent(arkPSBT, evt) require.ErrorContains(t, err, "root and pkscript mismatch") + + evt.TaprootAssetRoot = assetRoot[:] + evt.TaprootAssetAmount = 0 + _, err = incomingRecipientsFromEvent(arkPSBT, evt) + require.ErrorContains(t, err, "ref and amount must both be provided") + + evt.TaprootAssetAmount = 21 + evt.TaprootAssetRef = string( + make( + []byte, oortx.MaxTaprootAssetRefBytes+1, + ), + ) + _, err = incomingRecipientsFromEvent(arkPSBT, evt) + require.ErrorContains(t, err, "asset ref exceeds") } diff --git a/oor/incoming_vtxo.go b/oor/incoming_vtxo.go index 436e29b47..4b34267cd 100644 --- a/oor/incoming_vtxo.go +++ b/oor/incoming_vtxo.go @@ -95,6 +95,14 @@ type IncomingVTXOConfig struct { // TaprootAssetRoot is the optional asset commitment root composed next // to PolicyTemplate in the recipient output. TaprootAssetRoot *chainhash.Hash + + // TaprootAssetRef is the opaque SDK-level identity carried by the + // recipient output. + TaprootAssetRef string + + // TaprootAssetAmount is the number of asset units carried by the + // recipient output. The Ark output value remains carrier satoshis. + TaprootAssetAmount uint64 } // BuildIncomingVTXODescriptor constructs a VTXO descriptor for a recipient @@ -122,6 +130,21 @@ func BuildIncomingVTXODescriptor(ark *psbt.Packet, case cfg.Metadata.ChainDepth < 0: return nil, fmt.Errorf("chain depth must be "+ "non-negative, got %d", cfg.Metadata.ChainDepth) + + case cfg.TaprootAssetRoot == nil && + (cfg.TaprootAssetRef != "" || cfg.TaprootAssetAmount != 0): + return nil, fmt.Errorf("Taproot Asset metadata requires a " + + "commitment root") + + case cfg.TaprootAssetRoot != nil && + ((cfg.TaprootAssetRef == "") != + (cfg.TaprootAssetAmount == 0)): + return nil, fmt.Errorf("Taproot Asset ref and amount must " + + "both be provided") + + case len(cfg.TaprootAssetRef) > vtxo.MaxTaprootAssetRefBytes: + return nil, fmt.Errorf("Taproot Asset ref exceeds %d bytes", + vtxo.MaxTaprootAssetRefBytes) } if cfg.Metadata.CommitmentTxID == (chainhash.Hash{}) { @@ -173,21 +196,23 @@ func BuildIncomingVTXODescriptor(ark *psbt.Packet, Hash: arkTxid, Index: cfg.OutputIndex, }, - Amount: btcutil.Amount(out.Value), - PolicyTemplate: policyTemplate, - PkScript: out.PkScript, - TaprootAssetRoot: cfg.TaprootAssetRoot, - ClientKey: cfg.ClientKey, - OperatorKey: cfg.OperatorKey, - TapScript: tapscript, - Ancestry: ancestry, - RoundID: cfg.Metadata.RoundID, - CommitmentTxID: cfg.Metadata.CommitmentTxID, - BatchExpiry: cfg.Metadata.BatchExpiry, - RelativeExpiry: cfg.ExitDelay, - ChainDepth: cfg.Metadata.ChainDepth, - CreatedHeight: cfg.Metadata.CreatedHeight, - Status: vtxo.VTXOStatusLive, + Amount: btcutil.Amount(out.Value), + PolicyTemplate: policyTemplate, + PkScript: out.PkScript, + TaprootAssetRoot: cfg.TaprootAssetRoot, + TaprootAssetRef: cfg.TaprootAssetRef, + TaprootAssetAmount: cfg.TaprootAssetAmount, + ClientKey: cfg.ClientKey, + OperatorKey: cfg.OperatorKey, + TapScript: tapscript, + Ancestry: ancestry, + RoundID: cfg.Metadata.RoundID, + CommitmentTxID: cfg.Metadata.CommitmentTxID, + BatchExpiry: cfg.Metadata.BatchExpiry, + RelativeExpiry: cfg.ExitDelay, + ChainDepth: cfg.Metadata.ChainDepth, + CreatedHeight: cfg.Metadata.CreatedHeight, + Status: vtxo.VTXOStatusLive, }, nil } diff --git a/oor/incoming_vtxo_test.go b/oor/incoming_vtxo_test.go index 3f7aa6547..dfe4bc299 100644 --- a/oor/incoming_vtxo_test.go +++ b/oor/incoming_vtxo_test.go @@ -426,8 +426,10 @@ func TestBuildIncomingVTXODescriptorPreservesTaprootAssetRoot(t *testing.T) { require.NoError(t, err) assetRoot := chainhash.Hash{0x91, 0x92, 0x93} assetDesc := &vtxo.Descriptor{ - PolicyTemplate: template, - TaprootAssetRoot: &assetRoot, + PolicyTemplate: template, + TaprootAssetRoot: &assetRoot, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, } assetPkScript, err := assetDesc.EffectivePkScript() require.NoError(t, err) @@ -439,10 +441,12 @@ func TestBuildIncomingVTXODescriptorPreservesTaprootAssetRoot(t *testing.T) { ClientKey: keychain.KeyDescriptor{ PubKey: recipientKey.PubKey(), }, - OperatorKey: operatorKey, - ExitDelay: 10, - PolicyTemplate: template, - TaprootAssetRoot: &assetRoot, + OperatorKey: operatorKey, + ExitDelay: 10, + PolicyTemplate: template, + TaprootAssetRoot: &assetRoot, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, Metadata: IncomingVTXOMetadata{ RoundID: "test-round", CommitmentTxID: commitHash, @@ -457,6 +461,8 @@ func TestBuildIncomingVTXODescriptorPreservesTaprootAssetRoot(t *testing.T) { desc, err := BuildIncomingVTXODescriptor(arkPSBT, cfg) require.NoError(t, err) require.Equal(t, &assetRoot, desc.TaprootAssetRoot) + require.Equal(t, "asset-id:010203", desc.TaprootAssetRef) + require.Equal(t, uint64(21), desc.TaprootAssetAmount) require.Equal(t, assetPkScript, desc.PkScript) wrongRoot := assetRoot diff --git a/oor/local_persistence_handler.go b/oor/local_persistence_handler.go index dfae3e266..eae6fc3e9 100644 --- a/oor/local_persistence_handler.go +++ b/oor/local_persistence_handler.go @@ -431,7 +431,10 @@ func (h *LocalPersistenceOutboxHandler) materializeIncoming(ctx context.Context, PolicyTemplate: recipient. VTXOPolicyTemplate, TaprootAssetRoot: recipient.TaprootAssetRoot, - Metadata: metadata, + TaprootAssetRef: recipient.TaprootAssetRef, + TaprootAssetAmount: recipient. + TaprootAssetAmount, + Metadata: metadata, }, ) if err != nil { @@ -462,6 +465,11 @@ func (h *LocalPersistenceOutboxHandler) materializeIncoming(ctx context.Context, ) { return nil, err } + if existing.TaprootAssetRef != desc.TaprootAssetRef || + existing.TaprootAssetAmount != + desc.TaprootAssetAmount { + return nil, err + } desc = existing } diff --git a/oor/local_persistence_handler_test.go b/oor/local_persistence_handler_test.go index 1d58789f2..05318ce87 100644 --- a/oor/local_persistence_handler_test.go +++ b/oor/local_persistence_handler_test.go @@ -238,8 +238,10 @@ func TestLocalPersistenceOutboxHandlerMaterializeIncoming(t *testing.T) { require.NoError(t, err) assetRoot := chainhash.Hash{0x81, 0x82, 0x83} assetDesc := &vtxo.Descriptor{ - PolicyTemplate: policyTemplate, - TaprootAssetRoot: &assetRoot, + PolicyTemplate: policyTemplate, + TaprootAssetRoot: &assetRoot, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, } assetPkScript, err := assetDesc.EffectivePkScript() require.NoError(t, err) @@ -248,6 +250,8 @@ func TestLocalPersistenceOutboxHandlerMaterializeIncoming(t *testing.T) { recipients[0].PkScript = assetPkScript recipients[0].VTXOPolicyTemplate = policyTemplate recipients[0].TaprootAssetRoot = &assetRoot + recipients[0].TaprootAssetRef = "asset-id:010203" + recipients[0].TaprootAssetAmount = 21 assetTransfer := &oortx.TaprootAssetTransfer{ Version: oortx.TaprootAssetTransferVersion, CheckpointPackages: [][]byte{ @@ -340,6 +344,8 @@ func TestLocalPersistenceOutboxHandlerMaterializeIncoming(t *testing.T) { require.EqualValues(t, 1, desc.MaxTreeDepth()) require.EqualValues(t, 700, desc.CreatedHeight) require.Equal(t, &assetRoot, desc.TaprootAssetRoot) + require.Equal(t, "asset-id:010203", desc.TaprootAssetRef) + require.Equal(t, uint64(21), desc.TaprootAssetAmount) require.Equal(t, assetTransfer, packageStore.lastAssetTransfer) // Re-materialization should be idempotent. diff --git a/oor/outbox_error_test.go b/oor/outbox_error_test.go index cba22e607..79907ae12 100644 --- a/oor/outbox_error_test.go +++ b/oor/outbox_error_test.go @@ -423,6 +423,8 @@ func TestReceiveNotifiedAssetTransferSnapshotRoundTrip(t *testing.T) { sessionID := SessionID(arkPSBT.UnsignedTx.TxHash()) assetRoot := chainhash.Hash{0x63, 0x64, 0x65} recipients[0].TaprootAssetRoot = &assetRoot + recipients[0].TaprootAssetRef = "asset-id:010203" + recipients[0].TaprootAssetAmount = 21 assetTransfer := &oortx.TaprootAssetTransfer{ Version: oortx.TaprootAssetTransferVersion, CheckpointPackages: [][]byte{ @@ -443,7 +445,7 @@ func TestReceiveNotifiedAssetTransferSnapshotRoundTrip(t *testing.T) { TaprootAssetTransfer: assetTransfer, }) require.NoError(t, err) - require.Equal(t, uint8(2), snapshot.Version) + require.Equal(t, uint8(3), snapshot.Version) raw, err := encodeIncomingSnapshot(snapshot) require.NoError(t, err) @@ -457,6 +459,11 @@ func TestReceiveNotifiedAssetTransferSnapshotRoundTrip(t *testing.T) { require.True(t, ok) require.Equal(t, &assetRoot, notified.Recipients[0].TaprootAssetRoot) + require.Equal( + t, "asset-id:010203", notified.Recipients[0].TaprootAssetRef, + ) + require.Equal(t, uint64(21), + notified.Recipients[0].TaprootAssetAmount) require.Equal(t, assetTransfer, notified.TaprootAssetTransfer) } diff --git a/oor/outbox_messages.go b/oor/outbox_messages.go index 08d8db6f1..19f7392a6 100644 --- a/oor/outbox_messages.go +++ b/oor/outbox_messages.go @@ -171,6 +171,8 @@ func (m *SendSubmitPackageRequest) ToProto() fn.Result[proto.Message] { SpendPath: spendPathRaw, OwnerLeafPolicy: ti.OwnerLeafPolicy, TaprootAssetRoot: ti.TaprootAssetRoot, + TaprootAssetRef: ti.VTXO.TaprootAssetRef, + TaprootAssetAmount: ti.VTXO.TaprootAssetAmount, } descs = append(descs, desc) } diff --git a/oor/outgoing_snapshot.go b/oor/outgoing_snapshot.go index 100bf8e13..d015fd149 100644 --- a/oor/outgoing_snapshot.go +++ b/oor/outgoing_snapshot.go @@ -126,10 +126,11 @@ func NewOutgoingSnapshot(sessionID SessionID, } snap := &OutgoingSnapshot{ - // Version 6 adds the recipient and Taproot Asset transfer - // records. Restore remains backward-compatible because both TLV - // records are optional when decoding older snapshots. - Version: 6, + // Version 7 adds SDK-neutral asset identity and amount within + // the recipient and input records. Restore remains + // backward-compatible because the appended TLV fields are + // optional. + Version: 7, SessionID: sessionID, } @@ -603,6 +604,8 @@ func cloneRecipientOutputs( VTXOPolicyTemplate: bytes.Clone( recipients[i].VTXOPolicyTemplate, ), + TaprootAssetRef: recipients[i].TaprootAssetRef, + TaprootAssetAmount: recipients[i].TaprootAssetAmount, } if recipients[i].TaprootAssetRoot != nil { root := *recipients[i].TaprootAssetRoot diff --git a/oor/outgoing_snapshot_codec.go b/oor/outgoing_snapshot_codec.go index 353e0c66a..61ef345a2 100644 --- a/oor/outgoing_snapshot_codec.go +++ b/oor/outgoing_snapshot_codec.go @@ -70,6 +70,10 @@ func encodeOutgoingSnapshot(snapshot *OutgoingSnapshot) ([]byte, error) { VTXOPolicyTemplate, TaprootAssetRoot: snapshot.RecipientOutputs[i]. TaprootAssetRoot, + TaprootAssetRef: snapshot.RecipientOutputs[i]. + TaprootAssetRef, + TaprootAssetAmount: snapshot.RecipientOutputs[i]. + TaprootAssetAmount, }) } recipientOutputs, err := encodeRecipientPayloads(recipientPayloads) @@ -247,6 +251,10 @@ func decodeOutgoingSnapshotWithLimits(raw []byte, VTXOPolicyTemplate, TaprootAssetRoot: recipient. TaprootAssetRoot, + TaprootAssetRef: recipient. + TaprootAssetRef, + TaprootAssetAmount: recipient. + TaprootAssetAmount, }, ) } diff --git a/oor/prepared_submit.go b/oor/prepared_submit.go index 696f5f574..e40346633 100644 --- a/oor/prepared_submit.go +++ b/oor/prepared_submit.go @@ -58,9 +58,13 @@ func (p *PreparedSubmitPackage) Validate(inputs []TransferInput, if err := inputs[i].Validate(); err != nil { return fmt.Errorf("prepared input %d: %w", i, err) } - if inputs[i].TaprootAssetRoot == nil { - return fmt.Errorf("prepared input %d asset root is "+ - "required", i) + hasAssetRoot := inputs[i].TaprootAssetRoot != nil + hasAssetPackage := len( + p.TaprootAssetTransfer.CheckpointPackages[i], + ) != 0 + if hasAssetRoot != hasAssetPackage { + return fmt.Errorf("prepared input %d asset root and "+ + "checkpoint package presence mismatch", i) } checkpoint := p.CheckpointPSBTs[i] @@ -83,11 +87,11 @@ func (p *PreparedSubmitPackage) Validate(inputs []TransferInput, if len(actualRecipients) != len(canonicalRecipients) { return fmt.Errorf("prepared recipient count mismatch") } + assetRecipients := 0 for i := range canonicalRecipients { recipient := canonicalRecipients[i] - if recipient.TaprootAssetRoot == nil { - return fmt.Errorf("prepared recipient %d asset root "+ - "is required", i) + if recipient.TaprootAssetRoot != nil { + assetRecipients++ } err := recipient.ValidateTaprootAssetCommitment() if err != nil { @@ -100,6 +104,10 @@ func (p *PreparedSubmitPackage) Validate(inputs []TransferInput, "mismatch", i) } } + if assetRecipients == 0 { + return fmt.Errorf("prepared recipients require at least one " + + "asset-bearing output") + } return nil } diff --git a/oor/prepared_submit_test.go b/oor/prepared_submit_test.go index 9933b7093..51b50b961 100644 --- a/oor/prepared_submit_test.go +++ b/oor/prepared_submit_test.go @@ -3,6 +3,7 @@ package oor import ( "bytes" "context" + "fmt" "testing" "github.com/btcsuite/btcd/btcec/v2" @@ -105,6 +106,7 @@ func TestPreparedSubmitRejectsMismatchedAssetMetadata(t *testing.T) { wrongRoot := *inputs[0].TaprootAssetRoot wrongRoot[0] ^= 1 inputs[0].TaprootAssetRoot = &wrongRoot + inputs[0].VTXO.TaprootAssetRoot = &wrongRoot err := prepared.Validate(inputs, recipients) require.ErrorContains(t, err, "asset root and vtxo pkscript mismatch") @@ -117,6 +119,122 @@ func TestPreparedSubmitRejectsMismatchedAssetMetadata(t *testing.T) { require.ErrorContains(t, err, "does not match checkpoint count") } +// TestPreparedSubmitAcceptsMixedBitcoinInputs pins positional empty checkpoint +// slots for an asset input combined with zero, one, or several ordinary VTXOs. +func TestPreparedSubmitAcceptsMixedBitcoinInputs(t *testing.T) { + t.Parallel() + + assetVersion := oortx.TaprootAssetTransferVersion + for _, bitcoinInputs := range []int{0, 1, 3} { + bitcoinInputs := bitcoinInputs + t.Run(fmt.Sprintf("bitcoin_inputs_%d", bitcoinInputs), + func(t *testing.T) { + t.Parallel() + + policy, inputs, recipients, _ := + testPreparedSubmitPackage(t) + inputs, recipients = appendBitcoinPreparedEdges( + t, policy, inputs, recipients, + bitcoinInputs, + ) + ark, checkpoints, err := BuildSubmitPackage( + policy, inputs, recipients, + ) + require.NoError(t, err) + + slots := make([][]byte, len(inputs)) + slots[0] = []byte("asset-checkpoint") + assetTransfer := &oortx.TaprootAssetTransfer{ + Version: assetVersion, + CheckpointPackages: slots, + ArkPackage: []byte("ark"), + } + prepared := &PreparedSubmitPackage{ + ArkPSBT: ark, + CheckpointPSBTs: checkpoints, + TaprootAssetTransfer: assetTransfer, + } + require.NoError( + t, + prepared.Validate(inputs, recipients), + ) + + if bitcoinInputs == 0 { + return + } + prepared.TaprootAssetTransfer. + CheckpointPackages[1] = []byte("wrong") + err = prepared.Validate(inputs, recipients) + require.ErrorContains( + t, err, "package presence mismatch", + ) + }) + } +} + +func appendBitcoinPreparedEdges(t *testing.T, policy arkscript.CheckpointPolicy, + inputs []TransferInput, recipients []oortx.RecipientOutput, + count int) ([]TransferInput, []oortx.RecipientOutput) { + + t.Helper() + for idx := range count { + ownerKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + inputPolicy, err := arkscript.NewVTXOPolicy( + ownerKey.PubKey(), policy.OperatorKey, policy.CSVDelay, + ) + require.NoError(t, err) + inputPolicyRaw, err := inputPolicy.Template.Encode() + require.NoError(t, err) + inputPkScript, err := inputPolicy.Template.PkScript() + require.NoError(t, err) + inputTapScript, err := arkscript.VTXOTapScript( + ownerKey.PubKey(), policy.OperatorKey, policy.CSVDelay, + ) + require.NoError(t, err) + value := btcutil.Amount(1_000 + idx) + inputs = append(inputs, TransferInput{ + VTXO: &vtxo.Descriptor{ + Outpoint: wire.OutPoint{ + Hash: chainhash.Hash{byte(idx + 20)}, + Index: uint32(idx), + }, + Amount: value, + PkScript: inputPkScript, + ClientKey: keychain.KeyDescriptor{ + PubKey: ownerKey.PubKey(), + }, + OperatorKey: policy.OperatorKey, + TapScript: inputTapScript, + RelativeExpiry: policy.CSVDelay, + Status: vtxo.VTXOStatusLive, + }, + VTXOPolicyTemplate: inputPolicyRaw, + }) + + recipientKey, err := btcec.NewPrivateKey() + require.NoError(t, err) + recipientPolicy, err := arkscript.NewVTXOPolicy( + recipientKey.PubKey(), policy.OperatorKey, + policy.CSVDelay, + ) + require.NoError(t, err) + recipientPolicyRaw, err := recipientPolicy.Template.Encode() + require.NoError(t, err) + recipientPkScript, err := recipientPolicy.Template.PkScript() + require.NoError(t, err) + recipients = append(recipients, oortx.RecipientOutput{ + PkScript: recipientPkScript, + Value: value, + VTXOPolicyTemplate: recipientPolicyRaw, + }) + } + + require.NoError(t, NormalizeCheckpointOwnerLeaves(policy, inputs)) + + return inputs, recipients +} + func testPreparedSubmitPackage(t *testing.T) (arkscript.CheckpointPolicy, []TransferInput, []oortx.RecipientOutput, *PreparedSubmitPackage) { @@ -170,10 +288,13 @@ func testPreparedSubmitPackage(t *testing.T) (arkscript.CheckpointPolicy, }, PubKey: ownerKey.PubKey(), }, - OperatorKey: operatorKey.PubKey(), - TapScript: inputTapScript, - RelativeExpiry: 10, - Status: vtxo.VTXOStatusLive, + OperatorKey: operatorKey.PubKey(), + TapScript: inputTapScript, + RelativeExpiry: 10, + Status: vtxo.VTXOStatusLive, + TaprootAssetRoot: &inputAssetRoot, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, }, VTXOPolicyTemplate: inputPolicyRaw, TaprootAssetRoot: &inputAssetRoot, @@ -202,6 +323,8 @@ func testPreparedSubmitPackage(t *testing.T) (arkscript.CheckpointPolicy, Value: 5_000, VTXOPolicyTemplate: recipientPolicyRaw, TaprootAssetRoot: &recipientAssetRoot, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, }} ark, checkpoints, err := BuildSubmitPackage( diff --git a/oor/receive_snapshot.go b/oor/receive_snapshot.go index e10cf0fed..218516c9d 100644 --- a/oor/receive_snapshot.go +++ b/oor/receive_snapshot.go @@ -122,7 +122,10 @@ func NewIncomingSnapshot(sessionID SessionID, } snap := &IncomingSnapshot{ - Version: 2, + // Version 3 adds SDK-neutral asset identity and amount within + // the incoming recipient record. The appended TLV fields are + // optional. + Version: 3, SessionID: sessionID, } diff --git a/oor/taproot_asset_preparer.go b/oor/taproot_asset_preparer.go index 605df34a7..97418b953 100644 --- a/oor/taproot_asset_preparer.go +++ b/oor/taproot_asset_preparer.go @@ -23,7 +23,7 @@ var ErrTaprootAssetCommitOutcomeUnknown = errors.New("taproot asset commit " + const ( // MaxTaprootAssetRefBytes bounds the opaque tap-sdk asset identifier at // the daemon boundary. - MaxTaprootAssetRefBytes = 512 + MaxTaprootAssetRefBytes = oortx.MaxTaprootAssetRefBytes // MaxTaprootAssetProofDeliveryBytes bounds host-owned receiver // metadata. diff --git a/oor/transfer_input_snapshot.go b/oor/transfer_input_snapshot.go index ba72679cd..c4d01b938 100644 --- a/oor/transfer_input_snapshot.go +++ b/oor/transfer_input_snapshot.go @@ -57,6 +57,14 @@ type TransferInputSnapshot struct { // commitment anchored in the spent VTXO. TaprootAssetRoot *chainhash.Hash + // TaprootAssetRef is the opaque SDK-level identity carried by the input + // VTXO. + TaprootAssetRef string + + // TaprootAssetAmount is the number of asset units carried by the input + // VTXO. AmountSat remains the Bitcoin carrier amount. + TaprootAssetAmount uint64 + // PkScript is the VTXO pkscript. Stored for custom spend paths // where the pkscript cannot be derived from keys + exit delay. PkScript []byte @@ -119,6 +127,8 @@ func (i *TransferInput) ToSnapshot() (*TransferInputSnapshot, error) { root := *i.TaprootAssetRoot snap.TaprootAssetRoot = &root } + snap.TaprootAssetRef = i.VTXO.TaprootAssetRef + snap.TaprootAssetAmount = i.VTXO.TaprootAssetAmount if i.VTXO.ClientKey.PubKey != nil { snap.ClientPubKey = @@ -217,10 +227,13 @@ func TransferInputFromSnapshot(snap *TransferInputSnapshot) (TransferInput, }, PubKey: clientPub, }, - OperatorKey: operatorPub, - TapScript: tapScript, - RelativeExpiry: snap.ExitDelay, - Status: vtxo.VTXOStatusLive, + TaprootAssetRoot: snap.TaprootAssetRoot, + TaprootAssetRef: snap.TaprootAssetRef, + TaprootAssetAmount: snap.TaprootAssetAmount, + OperatorKey: operatorPub, + TapScript: tapScript, + RelativeExpiry: snap.ExitDelay, + Status: vtxo.VTXOStatusLive, } result := TransferInput{ diff --git a/oor/transfer_input_snapshot_test.go b/oor/transfer_input_snapshot_test.go index f8c882c6d..bee77e907 100644 --- a/oor/transfer_input_snapshot_test.go +++ b/oor/transfer_input_snapshot_test.go @@ -94,10 +94,13 @@ func TestTransferInputSnapshotRoundTrip(t *testing.T) { }, PubKey: clientKey.PubKey(), }, - OperatorKey: operatorKey.PubKey(), - TapScript: tapScript, - RelativeExpiry: exitDelay, - Status: vtxo.VTXOStatusLive, + OperatorKey: operatorKey.PubKey(), + TapScript: tapScript, + RelativeExpiry: exitDelay, + Status: vtxo.VTXOStatusLive, + TaprootAssetRoot: &assetRoot, + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, }, VTXOPolicyTemplate: vtxoPolicyTemplate, TaprootAssetRoot: &assetRoot, @@ -155,6 +158,9 @@ func TestTransferInputSnapshotRoundTrip(t *testing.T) { require.Equal(t, in.OwnerLeafPolicy, snap.OwnerLeafPolicy) require.Equal(t, in.VTXOPolicyTemplate, snap.VTXOPolicyTemplate) require.Equal(t, in.TaprootAssetRoot, snap.TaprootAssetRoot) + require.Equal(t, in.VTXO.TaprootAssetRef, snap.TaprootAssetRef) + require.Equal(t, in.VTXO.TaprootAssetAmount, + snap.TaprootAssetAmount) require.Equal(t, in.CustomSpend.RequiredSequence, snap.RequiredSequence) require.Equal(t, in.CustomSpend.RequiredLockTime, @@ -167,6 +173,9 @@ func TestTransferInputSnapshotRoundTrip(t *testing.T) { snap, err = decodeTransferInputSnapshot(rawSnapshot) require.NoError(t, err) require.Equal(t, in.TaprootAssetRoot, snap.TaprootAssetRoot) + require.Equal(t, in.VTXO.TaprootAssetRef, snap.TaprootAssetRef) + require.Equal(t, in.VTXO.TaprootAssetAmount, + snap.TaprootAssetAmount) rebuilt, err := TransferInputFromSnapshot(snap) require.NoError(t, err) @@ -192,6 +201,11 @@ func TestTransferInputSnapshotRoundTrip(t *testing.T) { require.Equal(t, in.OwnerLeafPolicy, rebuilt.OwnerLeafPolicy) require.Equal(t, in.VTXOPolicyTemplate, rebuilt.VTXOPolicyTemplate) require.Equal(t, in.TaprootAssetRoot, rebuilt.TaprootAssetRoot) + require.Equal(t, in.VTXO.TaprootAssetRef, + rebuilt.VTXO.TaprootAssetRef) + require.Equal( + t, in.VTXO.TaprootAssetAmount, rebuilt.VTXO.TaprootAssetAmount, + ) spendPath, err := rebuilt.EffectiveSpendPath() require.NoError(t, err) require.GreaterOrEqual(t, len(spendPath.ControlBlock), 32) @@ -215,9 +229,22 @@ func TestTransferInputSnapshotRoundTrip(t *testing.T) { t, in.ExternalSignatures[0], rebuilt.ExternalSignatures[0], ) + disagreedRoot := assetRoot + disagreedRoot[0] ^= 1 + rebuilt.TaprootAssetRoot = &disagreedRoot + err = rebuilt.Validate() + require.ErrorContains(t, err, "asset roots disagree") + rebuilt.TaprootAssetRoot = &assetRoot + + rebuilt.VTXO.TaprootAssetAmount = 0 + err = rebuilt.Validate() + require.ErrorContains(t, err, "ref and amount must both be provided") + rebuilt.VTXO.TaprootAssetAmount = in.VTXO.TaprootAssetAmount + wrongRoot := assetRoot wrongRoot[0] ^= 1 rebuilt.TaprootAssetRoot = &wrongRoot + rebuilt.VTXO.TaprootAssetRoot = &wrongRoot err = rebuilt.Validate() require.ErrorContains(t, err, "asset root and vtxo pkscript mismatch") } diff --git a/oor/transfer_inputs.go b/oor/transfer_inputs.go index 398a5125a..f589acf41 100644 --- a/oor/transfer_inputs.go +++ b/oor/transfer_inputs.go @@ -111,6 +111,30 @@ func (i *TransferInput) Validate() error { case !i.IsCustomSpend() && i.VTXO.ClientKey.PubKey == nil: return fmt.Errorf("vtxo client key must be provided") } + if (i.VTXO.TaprootAssetRef == "") != + (i.VTXO.TaprootAssetAmount == 0) { + return fmt.Errorf("vtxo asset ref and amount must both be " + + "provided") + } + if len(i.VTXO.TaprootAssetRef) > MaxTaprootAssetRefBytes { + return fmt.Errorf("vtxo asset ref exceeds %d bytes", + MaxTaprootAssetRefBytes) + } + if i.VTXO.TaprootAssetRef != "" && + i.VTXO.TaprootAssetRoot == nil { + return fmt.Errorf("vtxo asset metadata requires a commitment " + + "root") + } + if (i.TaprootAssetRoot == nil) != + (i.VTXO.TaprootAssetRoot == nil) { + return fmt.Errorf("transfer input and vtxo asset roots " + + "disagree") + } + if i.TaprootAssetRoot != nil && + *i.TaprootAssetRoot != *i.VTXO.TaprootAssetRoot { + return fmt.Errorf("transfer input and vtxo asset roots " + + "disagree") + } defaultLeaf, defaultPolicy, err := defaultOwnerLeaf( i.VTXO.ClientKey.PubKey, i.VTXO.OperatorKey, diff --git a/rpc/oorpb/oorwire.pb.go b/rpc/oorpb/oorwire.pb.go index 8743787d2..23bad169d 100644 --- a/rpc/oorpb/oorwire.pb.go +++ b/rpc/oorpb/oorwire.pb.go @@ -182,8 +182,12 @@ type OORSigningDescriptor struct { // taproot_asset_root is the optional 32-byte Taproot Asset commitment // root anchored in the spent VTXO. TaprootAssetRoot []byte `protobuf:"bytes,5,opt,name=taproot_asset_root,json=taprootAssetRoot,proto3" json:"taproot_asset_root,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // taproot_asset_ref is the canonical opaque SDK-level asset identity. + TaprootAssetRef string `protobuf:"bytes,6,opt,name=taproot_asset_ref,json=taprootAssetRef,proto3" json:"taproot_asset_ref,omitempty"` + // taproot_asset_amount is the number of asset units in the spent VTXO. + TaprootAssetAmount uint64 `protobuf:"varint,7,opt,name=taproot_asset_amount,json=taprootAssetAmount,proto3" json:"taproot_asset_amount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *OORSigningDescriptor) Reset() { @@ -251,6 +255,20 @@ func (x *OORSigningDescriptor) GetTaprootAssetRoot() []byte { return nil } +func (x *OORSigningDescriptor) GetTaprootAssetRef() string { + if x != nil { + return x.TaprootAssetRef + } + return "" +} + +func (x *OORSigningDescriptor) GetTaprootAssetAmount() uint64 { + if x != nil { + return x.TaprootAssetAmount + } + return 0 +} + // OORRecipientOutput carries one Ark recipient output plus optional semantic // policy metadata for the created VTXO. type OORRecipientOutput struct { @@ -265,8 +283,14 @@ type OORRecipientOutput struct { // taproot_asset_root is the optional 32-byte Taproot Asset commitment // root anchored in this recipient output. TaprootAssetRoot []byte `protobuf:"bytes,4,opt,name=taproot_asset_root,json=taprootAssetRoot,proto3" json:"taproot_asset_root,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this output. + TaprootAssetRef string `protobuf:"bytes,5,opt,name=taproot_asset_ref,json=taprootAssetRef,proto3" json:"taproot_asset_ref,omitempty"` + // taproot_asset_amount is the number of asset units carried by this + // output. value_sat remains the separate Bitcoin carrier amount. + TaprootAssetAmount uint64 `protobuf:"varint,6,opt,name=taproot_asset_amount,json=taprootAssetAmount,proto3" json:"taproot_asset_amount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *OORRecipientOutput) Reset() { @@ -327,6 +351,20 @@ func (x *OORRecipientOutput) GetTaprootAssetRoot() []byte { return nil } +func (x *OORRecipientOutput) GetTaprootAssetRef() string { + if x != nil { + return x.TaprootAssetRef + } + return "" +} + +func (x *OORRecipientOutput) GetTaprootAssetAmount() uint64 { + if x != nil { + return x.TaprootAssetAmount + } + return 0 +} + // SubmitPackageRequest carries submit-phase OOR data. type SubmitPackageRequest struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -768,19 +806,23 @@ const file_oorwire_proto_rawDesc = "" + "\roorwire.proto\x12\x05oorpb\"5\n" + "\vOOROutPoint\x12\x12\n" + "\x04txid\x18\x01 \x01(\fR\x04txid\x12\x12\n" + - "\x04vout\x18\x02 \x01(\rR\x04vout\"\xf1\x01\n" + + "\x04vout\x18\x02 \x01(\rR\x04vout\"\xcf\x02\n" + "\x14OORSigningDescriptor\x12.\n" + "\boutpoint\x18\x01 \x01(\v2\x12.oorpb.OOROutPointR\boutpoint\x120\n" + "\x14vtxo_policy_template\x18\x02 \x01(\fR\x12vtxoPolicyTemplate\x12\x1d\n" + "\n" + "spend_path\x18\x03 \x01(\fR\tspendPath\x12*\n" + "\x11owner_leaf_policy\x18\x04 \x01(\fR\x0fownerLeafPolicy\x12,\n" + - "\x12taproot_asset_root\x18\x05 \x01(\fR\x10taprootAssetRoot\"\xae\x01\n" + + "\x12taproot_asset_root\x18\x05 \x01(\fR\x10taprootAssetRoot\x12*\n" + + "\x11taproot_asset_ref\x18\x06 \x01(\tR\x0ftaprootAssetRef\x120\n" + + "\x14taproot_asset_amount\x18\a \x01(\x04R\x12taprootAssetAmount\"\x8c\x02\n" + "\x12OORRecipientOutput\x12\x1b\n" + "\tpk_script\x18\x01 \x01(\fR\bpkScript\x12\x1b\n" + "\tvalue_sat\x18\x02 \x01(\x03R\bvalueSat\x120\n" + "\x14vtxo_policy_template\x18\x03 \x01(\fR\x12vtxoPolicyTemplate\x12,\n" + - "\x12taproot_asset_root\x18\x04 \x01(\fR\x10taprootAssetRoot\"\xcb\x02\n" + + "\x12taproot_asset_root\x18\x04 \x01(\fR\x10taprootAssetRoot\x12*\n" + + "\x11taproot_asset_ref\x18\x05 \x01(\tR\x0ftaprootAssetRef\x120\n" + + "\x14taproot_asset_amount\x18\x06 \x01(\x04R\x12taprootAssetAmount\"\xcb\x02\n" + "\x14SubmitPackageRequest\x12\x19\n" + "\bark_psbt\x18\x01 \x01(\fR\aarkPsbt\x12)\n" + "\x10checkpoint_psbts\x18\x02 \x03(\fR\x0fcheckpointPsbts\x12L\n" + diff --git a/rpc/oorpb/oorwire.proto b/rpc/oorpb/oorwire.proto index a5fcea810..d9538de3f 100644 --- a/rpc/oorpb/oorwire.proto +++ b/rpc/oorpb/oorwire.proto @@ -46,6 +46,12 @@ message OORSigningDescriptor { // taproot_asset_root is the optional 32-byte Taproot Asset commitment // root anchored in the spent VTXO. bytes taproot_asset_root = 5; + + // taproot_asset_ref is the canonical opaque SDK-level asset identity. + string taproot_asset_ref = 6; + + // taproot_asset_amount is the number of asset units in the spent VTXO. + uint64 taproot_asset_amount = 7; } // OORRecipientOutput carries one Ark recipient output plus optional semantic @@ -64,6 +70,14 @@ message OORRecipientOutput { // taproot_asset_root is the optional 32-byte Taproot Asset commitment // root anchored in this recipient output. bytes taproot_asset_root = 4; + + // taproot_asset_ref is the opaque SDK-level asset identity carried by + // this output. + string taproot_asset_ref = 5; + + // taproot_asset_amount is the number of asset units carried by this + // output. value_sat remains the separate Bitcoin carrier amount. + uint64 taproot_asset_amount = 6; } // SubmitPackageRequest carries submit-phase OOR data. diff --git a/rpc/oorpb/payloads.go b/rpc/oorpb/payloads.go index 9e425893a..f306794de 100644 --- a/rpc/oorpb/payloads.go +++ b/rpc/oorpb/payloads.go @@ -46,6 +46,12 @@ type SigningDescriptor struct { // TaprootAssetRoot is the optional root of the Taproot Asset // commitment anchored in the spent VTXO. TaprootAssetRoot *chainhash.Hash + + // TaprootAssetRef is the canonical opaque SDK-level asset identity. + TaprootAssetRef string + + // TaprootAssetAmount is the number of asset units in the spent VTXO. + TaprootAssetAmount uint64 } // NewSubmitPackageRequest builds a typed proto request for SubmitPackage. @@ -90,6 +96,11 @@ func NewSubmitPackageRequestWithAssets(ark *psbt.Packet, []*OORRecipientOutput, 0, len(recipients), ) for i := range recipients { + err := recipients[i].ValidateTaprootAssetMetadata() + if err != nil { + return nil, fmt.Errorf("recipient output %d: %w", i, + err) + } var assetRoot []byte if recipients[i].TaprootAssetRoot != nil { assetRoot = recipients[i].TaprootAssetRoot.CloneBytes() @@ -101,6 +112,10 @@ func NewSubmitPackageRequestWithAssets(ark *psbt.Packet, VtxoPolicyTemplate: recipients[i]. VTXOPolicyTemplate, TaprootAssetRoot: assetRoot, + TaprootAssetRef: recipients[i]. + TaprootAssetRef, + TaprootAssetAmount: recipients[i]. + TaprootAssetAmount, }, ) } @@ -188,13 +203,21 @@ func ParseSubmitPackageRequestWithAssets(req *SubmitPackageRequest) ( return nil, nil, nil, nil, nil, err } - recipients = append(recipients, oortx.RecipientOutput{ + decodedRecipient := oortx.RecipientOutput{ PkScript: recipient.PkScript, Value: btcutil.Amount(recipient.ValueSat), VTXOPolicyTemplate: recipient. VtxoPolicyTemplate, - TaprootAssetRoot: assetRoot, - }) + TaprootAssetRoot: assetRoot, + TaprootAssetRef: recipient.TaprootAssetRef, + TaprootAssetAmount: recipient.TaprootAssetAmount, + } + err = decodedRecipient.ValidateTaprootAssetMetadata() + if err != nil { + return nil, nil, nil, nil, nil, fmt.Errorf("recipient "+ + "output %d: %w", i, err) + } + recipients = append(recipients, decodedRecipient) } var assetTransfer *oortx.TaprootAssetTransfer @@ -440,11 +463,17 @@ func ParseFinalizePackageResponse(resp *FinalizePackageResponse) ( func encodeSigningDescriptor(desc SigningDescriptor, index int) (*OORSigningDescriptor, error) { + if err := validateSigningDescriptorAssetMetadata(desc); err != nil { + return nil, fmt.Errorf("signing descriptor %d: %w", index, err) + } + proto := &OORSigningDescriptor{ Outpoint: encodeOutPoint(desc.Outpoint), VtxoPolicyTemplate: desc.VTXOPolicyTemplate, SpendPath: desc.SpendPath, OwnerLeafPolicy: desc.OwnerLeafPolicy, + TaprootAssetRef: desc.TaprootAssetRef, + TaprootAssetAmount: desc.TaprootAssetAmount, } if desc.TaprootAssetRoot != nil { proto.TaprootAssetRoot = desc.TaprootAssetRoot.CloneBytes() @@ -472,6 +501,8 @@ func decodeSigningDescriptor(desc *OORSigningDescriptor, VTXOPolicyTemplate: desc.VtxoPolicyTemplate, SpendPath: desc.SpendPath, OwnerLeafPolicy: desc.OwnerLeafPolicy, + TaprootAssetRef: desc.TaprootAssetRef, + TaprootAssetAmount: desc.TaprootAssetAmount, } result.TaprootAssetRoot, err = decodeOptionalHash( desc.TaprootAssetRoot, @@ -480,10 +511,22 @@ func decodeSigningDescriptor(desc *OORSigningDescriptor, if err != nil { return SigningDescriptor{}, err } + if err := validateSigningDescriptorAssetMetadata(result); err != nil { + return SigningDescriptor{}, fmt.Errorf("signing descriptor "+ + "%d: %w", index, err) + } return result, nil } +func validateSigningDescriptorAssetMetadata(desc SigningDescriptor) error { + return (oortx.RecipientOutput{ + TaprootAssetRoot: desc.TaprootAssetRoot, + TaprootAssetRef: desc.TaprootAssetRef, + TaprootAssetAmount: desc.TaprootAssetAmount, + }).ValidateTaprootAssetMetadata() +} + // decodeOptionalHash parses an optional 32-byte hash field. func decodeOptionalHash(raw []byte, name string) (*chainhash.Hash, error) { if len(raw) == 0 { diff --git a/rpc/oorpb/payloads_property_test.go b/rpc/oorpb/payloads_property_test.go index 4cd3f25ac..854046efd 100644 --- a/rpc/oorpb/payloads_property_test.go +++ b/rpc/oorpb/payloads_property_test.go @@ -54,6 +54,12 @@ func genSigningDescriptor(t *rapid.T) SigningDescriptor { if rapid.Bool().Draw(t, "has_asset_root") { root := genHash(t) desc.TaprootAssetRoot = &root + if rapid.Bool().Draw(t, "has_asset_metadata") { + desc.TaprootAssetRef = fmt.Sprintf("asset:%x", root[:]) + desc.TaprootAssetAmount = rapid.Uint64Range( + 1, ^uint64(0), + ).Draw(t, "asset_amount") + } } return desc @@ -119,6 +125,10 @@ func TestSigningDescriptorRoundTrip(t *testing.T) { require.Equal(t, desc.SpendPath, got.SpendPath) require.Equal(t, desc.OwnerLeafPolicy, got.OwnerLeafPolicy) require.Equal(t, desc.TaprootAssetRoot, got.TaprootAssetRoot) + require.Equal(t, desc.TaprootAssetRef, got.TaprootAssetRef) + require.Equal( + t, desc.TaprootAssetAmount, got.TaprootAssetAmount, + ) }) } @@ -179,6 +189,21 @@ func TestSubmitPackageRequestRoundTripProperty(t *testing.T) { root := genHash(rt) recipient.TaprootAssetRoot = &root + if rapid.Bool().Draw( + rt, fmt.Sprintf("recipient_has_asset"+ + "_metadata_%d", i), + ) { + + recipient.TaprootAssetRef = fmt.Sprintf( + "asset:%x", root[:]) + recipient.TaprootAssetAmount = + rapid.Uint64Range( + 1, ^uint64(0), + ).Draw( + rt, fmt.Sprintf( + "amt_%d", i), + ) + } } recipients[i] = recipient } @@ -224,6 +249,14 @@ func TestSubmitPackageRequestRoundTripProperty(t *testing.T) { t, descs[i].TaprootAssetRoot, gotDescs[i].TaprootAssetRoot, ) + require.Equal( + t, descs[i].TaprootAssetRef, + gotDescs[i].TaprootAssetRef, + ) + require.Equal( + t, descs[i].TaprootAssetAmount, + gotDescs[i].TaprootAssetAmount, + ) } require.Equal(t, recipients, gotRecipients) diff --git a/rpc/oorpb/payloads_test.go b/rpc/oorpb/payloads_test.go index 1560bc7fb..5a4844502 100644 --- a/rpc/oorpb/payloads_test.go +++ b/rpc/oorpb/payloads_test.go @@ -2,6 +2,7 @@ package oorpb import ( "bytes" + "strings" "testing" "github.com/btcsuite/btcd/chainhash/v2" @@ -46,7 +47,9 @@ func TestSubmitPackageRequestRoundTrip(t *testing.T) { 0x02, 0x03, }, - TaprootAssetRoot: &inputAssetRoot, + TaprootAssetRoot: &inputAssetRoot, + TaprootAssetRef: "asset:input", + TaprootAssetAmount: ^uint64(0), }} recipientAssetRoot := chainhash.Hash{4, 5, 6} recipients := []oortx.RecipientOutput{{ @@ -60,7 +63,9 @@ func TestSubmitPackageRequestRoundTrip(t *testing.T) { 0xaa, 0xbb, }, - TaprootAssetRoot: &recipientAssetRoot, + TaprootAssetRoot: &recipientAssetRoot, + TaprootAssetRef: "asset:recipient", + TaprootAssetAmount: 800, }} assetTransfer := &oortx.TaprootAssetTransfer{ Version: oortx.TaprootAssetTransferVersion, @@ -91,6 +96,12 @@ func TestSubmitPackageRequestRoundTrip(t *testing.T) { require.Equal( t, descs[0].TaprootAssetRoot, decDescs[0].TaprootAssetRoot, ) + require.Equal( + t, descs[0].TaprootAssetRef, decDescs[0].TaprootAssetRef, + ) + require.Equal( + t, descs[0].TaprootAssetAmount, decDescs[0].TaprootAssetAmount, + ) require.Equal(t, recipients, decRecipients) require.Equal(t, assetTransfer, decAssets) @@ -112,6 +123,152 @@ func TestSubmitPackageRequestRoundTrip(t *testing.T) { } } +// TestSubmitPackageRequestRejectsAssetMetadataShapes verifies both encoding +// and parsing fail closed when signing-descriptor or recipient metadata is +// partial or exceeds the bounded opaque asset-reference size. +func TestSubmitPackageRequestRejectsAssetMetadataShapes(t *testing.T) { + t.Parallel() + + root := chainhash.HashH([]byte("wire-asset-root")) + oversizedRef := strings.Repeat( + "a", oortx.MaxTaprootAssetRefBytes+1, + ) + encodeTests := []struct { + name string + descs []SigningDescriptor + recipients []oortx.RecipientOutput + want string + }{ + { + name: "signing descriptor partial", + descs: []SigningDescriptor{{ + TaprootAssetRoot: &root, + TaprootAssetRef: "asset:partial", + }}, + want: "asset ref and amount must both be provided", + }, + { + name: "signing descriptor oversized reference", + descs: []SigningDescriptor{{ + TaprootAssetRoot: &root, + TaprootAssetRef: oversizedRef, + TaprootAssetAmount: 1, + }}, + want: "asset ref exceeds", + }, + { + name: "recipient partial", + recipients: []oortx.RecipientOutput{{ + TaprootAssetRoot: &root, + TaprootAssetAmount: 1, + }}, + want: "asset ref and amount must both be provided", + }, + { + name: "recipient oversized reference", + recipients: []oortx.RecipientOutput{{ + TaprootAssetRoot: &root, + TaprootAssetRef: oversizedRef, + TaprootAssetAmount: 1, + }}, + want: "asset ref exceeds", + }, + } + for _, test := range encodeTests { + test := test + t.Run("encode "+test.name, func(t *testing.T) { + t.Parallel() + + _, err := NewSubmitPackageRequest( + mustTestPSBT(t, 0x71), nil, test.descs, + test.recipients, + ) + require.ErrorContains(t, err, test.want) + }) + } + + decodeTests := []struct { + name string + mutate func(*SubmitPackageRequest) + want string + }{ + { + name: "signing descriptor partial", + mutate: func(req *SubmitPackageRequest) { + assetRoot := root.CloneBytes() + desc := &OORSigningDescriptor{ + Outpoint: encodeOutPoint( + wire.OutPoint{}, + ), + TaprootAssetRoot: assetRoot, + TaprootAssetRef: "a", + } + descs := []*OORSigningDescriptor{ + desc, + } + req.SigningDescriptors = descs + }, + want: "asset ref and amount must both be provided", + }, + { + name: "signing descriptor oversized reference", + mutate: func(req *SubmitPackageRequest) { + assetRoot := root.CloneBytes() + assetRef := oversizedRef + desc := &OORSigningDescriptor{ + Outpoint: encodeOutPoint( + wire.OutPoint{}, + ), + TaprootAssetRoot: assetRoot, + TaprootAssetRef: assetRef, + TaprootAssetAmount: 1, + } + descs := []*OORSigningDescriptor{ + desc, + } + req.SigningDescriptors = descs + }, + want: "asset ref exceeds", + }, + { + name: "recipient partial", + mutate: func(req *SubmitPackageRequest) { + req.RecipientOutputs = []*OORRecipientOutput{{ + TaprootAssetRoot: root.CloneBytes(), + TaprootAssetAmount: 1, + }} + }, + want: "asset ref and amount must both be provided", + }, + { + name: "recipient oversized reference", + mutate: func(req *SubmitPackageRequest) { + req.RecipientOutputs = []*OORRecipientOutput{{ + TaprootAssetRoot: root.CloneBytes(), + TaprootAssetRef: oversizedRef, + TaprootAssetAmount: 1, + }} + }, + want: "asset ref exceeds", + }, + } + for _, test := range decodeTests { + test := test + t.Run("decode "+test.name, func(t *testing.T) { + t.Parallel() + + req, err := NewSubmitPackageRequest( + mustTestPSBT(t, 0x72), nil, nil, nil, + ) + require.NoError(t, err) + test.mutate(req) + + _, _, _, _, err = ParseSubmitPackageRequest(req) + require.ErrorContains(t, err, test.want) + }) + } +} + func TestParseSubmitPackageRequestRejectsInvalidAssetMetadata(t *testing.T) { t.Parallel() diff --git a/tapassets/driver.go b/tapassets/driver.go index 58493e61a..087539542 100644 --- a/tapassets/driver.go +++ b/tapassets/driver.go @@ -7,23 +7,45 @@ import ( tapsdk "github.com/lightninglabs/tap-sdk" ) +type commitProofSource struct { + kind tapsdk.CustomAnchorProofSourceKind + contentID tapsdk.Hash + blob []byte +} + type commitOutput struct { - anchorOutputIndex uint32 - anchorOutpoint tapsdk.Outpoint - anchorValueSat int64 - assetRef tapsdk.AssetRef - amount uint64 - taprootAssetRoot tapsdk.Hash - taprootMerkleRoot tapsdk.Hash - scriptKey tapsdk.PubKey - opTrueWitness [][]byte - proofBlob []byte + logicalOutputID string + logicalOutputIndex uint32 + packetIndex uint32 + packetRole tapsdk.CustomAnchorPacketRole + virtualOutputIndex uint32 + anchorOutputIndex uint32 + anchorOutpoint tapsdk.Outpoint + anchorValueSat int64 + assetRef tapsdk.AssetRef + issuanceID tapsdk.AssetID + amount uint64 + taprootAssetRoot tapsdk.Hash + taprootMerkleRoot tapsdk.Hash + scriptKey tapsdk.PubKey + scriptMode tapsdk.CustomAssetScriptMode + opTrueWitness [][]byte + proofBlob []byte } type commitInput struct { - anchorOutpoint tapsdk.Outpoint - assetRef tapsdk.AssetRef - amount uint64 + logicalInputID string + logicalInputIndex uint32 + packetIndex uint32 + packetRole tapsdk.CustomAnchorPacketRole + virtualInputIndex uint32 + anchorInputIndex uint32 + anchorOutpoint tapsdk.Outpoint + assetRef tapsdk.AssetRef + issuanceID tapsdk.AssetID + scriptKey tapsdk.PubKey + amount uint64 + proofSource commitProofSource } type commitResult struct { @@ -201,9 +223,24 @@ func commitResultFromPackage(transfer *tapsdk.CustomAnchorTransferPackage) ( for idx := range transfer.Inputs { input := transfer.Inputs[idx] result.inputs[idx] = commitInput{ - anchorOutpoint: input.AnchorOutpoint, - assetRef: input.AssetRef, - amount: input.Amount, + logicalInputID: input.LogicalInputID, + logicalInputIndex: input.LogicalInputIndex, + packetIndex: input.PacketIndex, + packetRole: input.PacketRole, + virtualInputIndex: input.VirtualInputIndex, + anchorInputIndex: input.AnchorInputIndex, + anchorOutpoint: input.AnchorOutpoint, + assetRef: input.AssetRef, + issuanceID: input.IssuanceID, + scriptKey: input.ScriptKey, + amount: input.Amount, + proofSource: commitProofSource{ + kind: input.ProofSource.Kind, + contentID: input.ProofSource.ContentID, + blob: append( + []byte(nil), input.ProofSource.Blob..., + ), + }, } } for idx := range transfer.Outputs { @@ -213,22 +250,41 @@ func commitResultFromPackage(transfer *tapsdk.CustomAnchorTransferPackage) ( witness = output.OPTrueSpend.WitnessStack() } result.outputs[idx] = commitOutput{ - anchorOutputIndex: output.AnchorOutputIndex, - anchorOutpoint: output.AnchorOutpoint, - anchorValueSat: output.AnchorValueSat, - assetRef: output.AssetRef, - amount: output.Amount, - taprootAssetRoot: output.TaprootAssetRoot, - taprootMerkleRoot: output.TaprootMerkleRoot, - scriptKey: output.ScriptKey, - opTrueWitness: witness, + logicalOutputID: output.LogicalOutputID, + logicalOutputIndex: output.LogicalOutputIndex, + packetIndex: output.PacketIndex, + packetRole: output.PacketRole, + virtualOutputIndex: output.VirtualOutputIndex, + anchorOutputIndex: output.AnchorOutputIndex, + anchorOutpoint: output.AnchorOutpoint, + anchorValueSat: output.AnchorValueSat, + assetRef: output.AssetRef, + issuanceID: output.IssuanceID, + amount: output.Amount, + taprootAssetRoot: output.TaprootAssetRoot, + taprootMerkleRoot: output.TaprootMerkleRoot, + scriptKey: output.ScriptKey, + scriptMode: output.ScriptMode, + opTrueWitness: witness, } } for idx := range transfer.ProofUpdates { update := transfer.ProofUpdates[idx] for outputIdx := range result.outputs { output := &result.outputs[outputIdx] - if output.anchorOutpoint == update.AnchorOutpoint && + if output.logicalOutputID == update.LogicalOutputID && + output.logicalOutputIndex == + update.LogicalOutputIndex && + output.packetIndex == update.PacketIndex && + output.packetRole == update.PacketRole && + output.virtualOutputIndex == + update.VirtualOutputIndex && + output.anchorOutputIndex == + update.AnchorOutputIndex && + output.anchorOutpoint == + update.AnchorOutpoint && + output.assetRef.Equivalent(update.AssetRef) && + output.issuanceID == update.IssuanceID && output.scriptKey == update.ScriptKey { output.proofBlob = append( @@ -239,6 +295,12 @@ func commitResultFromPackage(transfer *tapsdk.CustomAnchorTransferPackage) ( } } } + for idx := range result.outputs { + if len(result.outputs[idx].proofBlob) == 0 { + return nil, fmt.Errorf("tap-sdk output %d has no "+ + "exact proof update", idx) + } + } return result, nil } diff --git a/tapassets/onboarding.go b/tapassets/onboarding.go index 18d49f11e..8ee8e458c 100644 --- a/tapassets/onboarding.go +++ b/tapassets/onboarding.go @@ -20,6 +20,7 @@ import ( tapsdk "github.com/lightninglabs/tap-sdk" "github.com/lightninglabs/wavelength/lib/arkscript" "github.com/lightninglabs/wavelength/lib/tx/psbtutil" + "github.com/lightninglabs/wavelength/vtxo" "github.com/lightningnetwork/lnd/keychain" ) @@ -58,10 +59,12 @@ type OnboardingKeyDeriver func(context.Context) (*keychain.KeyDescriptor, error) // OnboardingRegistration is the credential-free package sent to the // operator after tap-sdk has committed and Wavelength has signed the anchor. type OnboardingRegistration struct { - TransferPackage []byte - FinalAnchorPSBT []byte - PolicyTemplate []byte - TaprootAssetRoot tapsdk.Hash + TransferPackage []byte + FinalAnchorPSBT []byte + PolicyTemplate []byte + TaprootAssetRoot tapsdk.Hash + TaprootAssetRef string + TaprootAssetAmount uint64 } // OnboardingRegistrationResult is the operator's confirmed admission result. @@ -89,6 +92,8 @@ type OnboardingResult struct { Status OnboardingStatus Outpoint wire.OutPoint ValueSat int64 + AssetRef string + AssetAmount uint64 ActualFeeSat uint64 PolicyTemplate []byte PkScript []byte @@ -304,6 +309,8 @@ func (o *Onboarder) Onboard(ctx context.Context, request *OnboardingRequest) ( TaprootAssetRoot: tapsdk.Hash( result.TaprootAssetRoot, ), + TaprootAssetRef: result.AssetRef, + TaprootAssetAmount: result.AssetAmount, }, ) if errors.Is(registerErr, ErrOnboardingPendingConfirmation) { @@ -644,6 +651,8 @@ func onboardingResultFromCommit(request *OnboardingRequest, return &OnboardingResult{ Outpoint: outpoint, ValueSat: output.anchorValueSat, + AssetRef: output.assetRef.String(), + AssetAmount: output.amount, ActualFeeSat: committed.actualFeeSat, PolicyTemplate: append([]byte(nil), state.PolicyTemplate...), PkScript: pkScript, @@ -729,6 +738,10 @@ func validateOnboardingRequest(request *OnboardingRequest) error { return fmt.Errorf("taproot asset ref, amount, and proof are " + "required") } + if len(request.AssetRef) > vtxo.MaxTaprootAssetRefBytes { + return fmt.Errorf("taproot asset ref exceeds %d bytes", + vtxo.MaxTaprootAssetRefBytes) + } if request.CarrierValueSat == 0 { return fmt.Errorf("taproot asset onboarding carrier value is " + "required") diff --git a/tapassets/onboarding_test.go b/tapassets/onboarding_test.go index 7a4c9b1ba..ef7af90ae 100644 --- a/tapassets/onboarding_test.go +++ b/tapassets/onboarding_test.go @@ -85,6 +85,12 @@ func TestOnboarderResumesPendingConfirmation(t *testing.T) { require.Equal(t, int64(1_000), result.ValueSat) require.Equal(t, uint64(250), result.ActualFeeSat) require.NotZero(t, result.TaprootAssetRoot) + require.Equal(t, request.AssetRef, result.AssetRef) + require.Equal(t, request.AssetAmount, result.AssetAmount) + require.Equal(t, request.AssetRef, registrations[0].TaprootAssetRef) + require.Equal( + t, request.AssetAmount, registrations[0].TaprootAssetAmount, + ) require.NotEmpty(t, result.PolicyTemplate) require.NotEmpty(t, result.PkScript) diff --git a/tapassets/preparer.go b/tapassets/preparer.go index a7cec9bd6..705926b0e 100644 --- a/tapassets/preparer.go +++ b/tapassets/preparer.go @@ -918,6 +918,8 @@ func validateArkResult(request *oor.TaprootAssetOORPrepareRequest, recipients := cloneRecipients(request.Recipients) root := chainhash.Hash(output.taprootAssetRoot) recipients[0].TaprootAssetRoot = &root + recipients[0].TaprootAssetRef = output.assetRef.String() + recipients[0].TaprootAssetAmount = output.amount template, err := arkscript.DecodePolicyTemplate( recipients[0].VTXOPolicyTemplate, ) diff --git a/tapassets/preparer_test.go b/tapassets/preparer_test.go index dfd165a40..f7bf2aa0d 100644 --- a/tapassets/preparer_test.go +++ b/tapassets/preparer_test.go @@ -430,6 +430,11 @@ func cloneCommitResult(result *commitResult) *commitResult { clone.packageBytes = append([]byte(nil), result.packageBytes...) clone.anchorPSBT = append([]byte(nil), result.anchorPSBT...) clone.inputs = append([]commitInput(nil), result.inputs...) + for idx := range clone.inputs { + clone.inputs[idx].proofSource.blob = append( + []byte(nil), result.inputs[idx].proofSource.blob..., + ) + } clone.outputs = append([]commitOutput(nil), result.outputs...) for idx := range clone.outputs { clone.outputs[idx].opTrueWitness = cloneByteSlices( @@ -586,10 +591,13 @@ func testPreparationRequest(t *testing.T) (*oor.TaprootAssetOORPrepareRequest, }, PubKey: owner.PubKey(), }, - OperatorKey: operator.PubKey(), - TapScript: legacyTapScript, - RelativeExpiry: 10, - Status: vtxo.VTXOStatusLive, + OperatorKey: operator.PubKey(), + TapScript: legacyTapScript, + RelativeExpiry: 10, + Status: vtxo.VTXOStatusLive, + TaprootAssetRoot: &inputRoot, + TaprootAssetRef: assetRef.String(), + TaprootAssetAmount: 21, }, VTXOPolicyTemplate: inputPolicyBytes, TaprootAssetRoot: &inputRoot, diff --git a/tapassets/proof_source.go b/tapassets/proof_source.go new file mode 100644 index 000000000..349ff0a4d --- /dev/null +++ b/tapassets/proof_source.go @@ -0,0 +1,255 @@ +package tapassets + +import ( + "fmt" + + "github.com/btcsuite/btcd/chainhash/v2" + "github.com/btcsuite/btcd/wire/v2" + tapsdk "github.com/lightninglabs/tap-sdk" +) + +// ProofSourceKind identifies the durable base of a reconstructed asset proof +// path without exposing tap-sdk types outside this adapter package. +type ProofSourceKind uint8 + +const ( + // ProofSourceConfirmedFile starts at a complete confirmed proof file. + ProofSourceConfirmedFile ProofSourceKind = 1 + + // ProofSourceCompactPath extends an already checksummed compact path. + ProofSourceCompactPath ProofSourceKind = 2 +) + +// AssetPacketRole identifies the virtual packet collection selected by a +// durable logical mapping. +type AssetPacketRole uint8 + +const ( + // AssetPacketActive identifies the active transfer packet collection. + AssetPacketActive AssetPacketRole = 1 + + // AssetPacketPassive identifies the passive re-anchor collection. + AssetPacketPassive AssetPacketRole = 2 +) + +// CreatedAssetProofSource is the SDK-neutral, restart-stable material needed +// to spend one exact asset-bearing VTXO in a later custom-anchor transaction. +// Amount is measured in asset units; the carrier-satoshi amount remains on +// the VTXO descriptor. +type CreatedAssetProofSource struct { + LogicalInputID string + LogicalInputIndex uint32 + LogicalOutputID string + LogicalOutputIndex uint32 + PacketRole AssetPacketRole + PacketIndex uint32 + VirtualOutputIndex uint32 + AnchorOutputIndex uint32 + AnchorOutpoint wire.OutPoint + CarrierValueSat int64 + AssetRef string + AssetAmount uint64 + TaprootAssetRoot chainhash.Hash + ProofSourceKind ProofSourceKind + ProofSourceID [32]byte + ProofSourceBlob []byte + TransitionProof []byte + CompactProofPath []byte + OPTrueWitness wire.TxWitness +} + +// ResolveCreatedAssetProofSource validates a sealed tap-sdk package and +// resolves the exact proof path and OP_TRUE witness for a VTXO it created. +// The returned byte slices never alias packageBytes or tap-sdk-owned memory. +func ResolveCreatedAssetProofSource(packageBytes []byte, outpoint wire.OutPoint, + carrierValueSat int64, assetRef string, assetAmount uint64, + taprootAssetRoot chainhash.Hash) (*CreatedAssetProofSource, error) { + + if len(packageBytes) == 0 { + return nil, fmt.Errorf("sealed Taproot Asset package is " + + "required") + } + expectedRef, err := tapsdk.ParseAssetRef(assetRef) + if err != nil { + return nil, fmt.Errorf("parse Taproot Asset ref: %w", err) + } + if assetAmount == 0 { + return nil, fmt.Errorf("Taproot Asset amount is required") + } + if carrierValueSat <= 0 { + return nil, fmt.Errorf("carrier-satoshi value is required") + } + + driver := &sdkDriver{} + committed, err := driver.DecodePackage(packageBytes) + if err != nil { + return nil, err + } + + return resolveCreatedAssetProofSource( + committed, sdkOutpoint(outpoint), carrierValueSat, expectedRef, + assetAmount, tapsdk.Hash(taprootAssetRoot), + ) +} + +func resolveCreatedAssetProofSource(committed *commitResult, + outpoint tapsdk.Outpoint, carrierValueSat int64, + assetRef tapsdk.AssetRef, assetAmount uint64, + taprootAssetRoot tapsdk.Hash) (*CreatedAssetProofSource, error) { + + if committed == nil { + return nil, fmt.Errorf("committed Taproot Asset package is " + + "required") + } + + var selected *commitOutput + for idx := range committed.outputs { + output := &committed.outputs[idx] + if output.anchorOutpoint != outpoint || + output.anchorValueSat != carrierValueSat || + !output.assetRef.Equivalent(assetRef) || + output.amount != assetAmount || + output.taprootAssetRoot != taprootAssetRoot { + + continue + } + if selected != nil { + return nil, fmt.Errorf("created Taproot Asset output " + + "is ambiguous") + } + selected = output + } + if selected == nil { + return nil, fmt.Errorf("sealed package does not create the " + + "requested Taproot Asset output") + } + if selected.scriptMode != tapsdk.CustomAssetScriptOPTrue || + len(selected.opTrueWitness) == 0 { + return nil, fmt.Errorf("created Taproot Asset output is not " + + "spendable through OP_TRUE") + } + if len(selected.proofBlob) == 0 { + return nil, fmt.Errorf("created Taproot Asset output has no " + + "transition proof") + } + + step := tapsdk.AssetProofPathStep{ + TransitionProof: append([]byte(nil), selected.proofBlob...), + } + stepSummary, err := step.Summary() + if err != nil { + return nil, fmt.Errorf("summarize created asset proof: %w", err) + } + if stepSummary.AnchorOutpoint != selected.anchorOutpoint || + !stepSummary.AssetRef.Equivalent(selected.assetRef) || + stepSummary.IssuanceID != selected.issuanceID || + stepSummary.Amount != selected.amount || + stepSummary.ScriptKey != selected.scriptKey || + stepSummary.AnchorValueSat != selected.anchorValueSat { + return nil, fmt.Errorf("created asset proof does not match " + + "package output") + } + + var input *commitInput + for idx := range committed.inputs { + candidate := &committed.inputs[idx] + if candidate.anchorOutpoint != + stepSummary.PreviousAnchorOutpoint || + !candidate.assetRef.Equivalent(stepSummary.AssetRef) || + candidate.issuanceID != stepSummary.IssuanceID { + + continue + } + if input != nil { + return nil, fmt.Errorf("created asset proof has " + + "multiple possible predecessor inputs") + } + input = candidate + } + if input == nil { + return nil, fmt.Errorf("created asset proof predecessor is " + + "not present in the sealed package") + } + + path := &tapsdk.AssetProofPath{} + sourceKind, err := proofPathFromSource(input.proofSource, path) + if err != nil { + return nil, err + } + path.Steps = append(path.Steps, step) + compactPath, err := path.MarshalBinary() + if err != nil { + return nil, fmt.Errorf("encode extended asset proof path: %w", + err) + } + + return &CreatedAssetProofSource{ + LogicalInputID: input.logicalInputID, + LogicalInputIndex: input.logicalInputIndex, + LogicalOutputID: selected.logicalOutputID, + LogicalOutputIndex: selected.logicalOutputIndex, + PacketRole: assetPacketRole(selected.packetRole), + PacketIndex: selected.packetIndex, + VirtualOutputIndex: selected.virtualOutputIndex, + AnchorOutputIndex: selected.anchorOutputIndex, + AnchorOutpoint: wire.OutPoint{ + Hash: selected.anchorOutpoint.Txid, + Index: selected.anchorOutpoint.Index, + }, + CarrierValueSat: selected.anchorValueSat, + AssetRef: selected.assetRef.String(), + AssetAmount: selected.amount, + TaprootAssetRoot: chainhash.Hash(selected.taprootAssetRoot), + ProofSourceKind: sourceKind, + ProofSourceID: [32]byte(input.proofSource.contentID), + ProofSourceBlob: append( + []byte(nil), input.proofSource.blob..., + ), + TransitionProof: append([]byte(nil), selected.proofBlob...), + CompactProofPath: append([]byte(nil), compactPath...), + OPTrueWitness: wire.TxWitness( + cloneByteSlices(selected.opTrueWitness), + ), + }, nil +} + +func proofPathFromSource(source commitProofSource, + path *tapsdk.AssetProofPath) (ProofSourceKind, error) { + + switch source.kind { + case tapsdk.CustomAnchorProofSourceConfirmedFile: + *path = tapsdk.AssetProofPath{ + Version: tapsdk.AssetProofPathVersionV0, + ConfirmedBaseProof: append( + []byte(nil), source.blob..., + ), + } + + return ProofSourceConfirmedFile, nil + + case tapsdk.CustomAnchorProofSourceCompactPath: + if err := path.UnmarshalBinary(source.blob); err != nil { + return 0, fmt.Errorf("decode predecessor asset proof "+ + "path: %w", err) + } + + return ProofSourceCompactPath, nil + + default: + return 0, fmt.Errorf("unsupported Taproot Asset proof "+ + "source %d", source.kind) + } +} + +func assetPacketRole(role tapsdk.CustomAnchorPacketRole) AssetPacketRole { + switch role { + case tapsdk.CustomAnchorPacketRoleActive: + return AssetPacketActive + + case tapsdk.CustomAnchorPacketRolePassive: + return AssetPacketPassive + + default: + return 0 + } +} diff --git a/tapassets/proof_source_test.go b/tapassets/proof_source_test.go new file mode 100644 index 000000000..fd866b52d --- /dev/null +++ b/tapassets/proof_source_test.go @@ -0,0 +1,521 @@ +package tapassets + +import ( + "bytes" + "testing" + + "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/btcutil/v2" + "github.com/btcsuite/btcd/chainhash/v2" + "github.com/btcsuite/btcd/txscript/v2" + "github.com/btcsuite/btcd/wire/v2" + tapsdk "github.com/lightninglabs/tap-sdk" + "github.com/lightninglabs/taproot-assets/asset" + "github.com/lightninglabs/taproot-assets/commitment" + "github.com/lightninglabs/taproot-assets/proof" + "github.com/lightninglabs/taproot-assets/tapscript" + "github.com/lightningnetwork/lnd/keychain" + "github.com/stretchr/testify/require" +) + +// TestResolveCreatedAssetProofSource proves a sealed-package projection can be +// reconstructed byte-identically after restart without consulting tapd. +func TestResolveCreatedAssetProofSource(t *testing.T) { + t.Parallel() + + committed, expectedRef, expectedRoot := proofSourceCommitResult(t) + expectedOutpoint := committed.outputs[0].anchorOutpoint + + resolved, err := resolveCreatedAssetProofSource( + committed, expectedOutpoint, + committed.outputs[0].anchorValueSat, expectedRef, + committed.outputs[0].amount, tapsdk.Hash(expectedRoot), + ) + require.NoError(t, err) + require.Equal(t, "input-0", resolved.LogicalInputID) + require.Equal(t, "output-0", resolved.LogicalOutputID) + require.Equal(t, AssetPacketActive, resolved.PacketRole) + require.Equal(t, expectedRef.String(), resolved.AssetRef) + require.Equal(t, uint64(100), resolved.AssetAmount) + require.Equal(t, int64(330), resolved.CarrierValueSat) + require.Equal(t, expectedRoot, resolved.TaprootAssetRoot) + require.Equal(t, ProofSourceConfirmedFile, + resolved.ProofSourceKind) + require.Equal( + t, committed.outputs[0].proofBlob, resolved.TransitionProof, + ) + require.Equal( + t, wire.TxWitness{{txscript.OP_TRUE}, {1, 2, 3}}, + resolved.OPTrueWitness, + ) + + var path tapsdk.AssetProofPath + require.NoError(t, path.UnmarshalBinary(resolved.CompactProofPath)) + require.Len(t, path.Steps, 1) + require.Equal( + t, committed.outputs[0].proofBlob, + path.Steps[0].TransitionProof, + ) + + // Mutating one result must not alter the package projection or the next + // resolution performed by a fresh process instance. + resolved.ProofSourceBlob[0] ^= 1 + resolved.TransitionProof[0] ^= 1 + resolved.CompactProofPath[0] ^= 1 + resolved.OPTrueWitness[0][0] ^= 1 + restarted, err := resolveCreatedAssetProofSource( + cloneCommitResult(committed), expectedOutpoint, + committed.outputs[0].anchorValueSat, expectedRef, + committed.outputs[0].amount, tapsdk.Hash(expectedRoot), + ) + require.NoError(t, err) + require.Equal( + t, committed.inputs[0].proofSource.blob, + restarted.ProofSourceBlob, + ) + require.Equal( + t, committed.outputs[0].proofBlob, restarted.TransitionProof, + ) + require.Equal( + t, wire.TxWitness{{txscript.OP_TRUE}, {1, 2, 3}}, + restarted.OPTrueWitness, + ) +} + +// TestResolveCreatedAssetProofSourceExtendsCompactPath verifies the same +// resolver appends to an existing compact source rather than replacing it. +func TestResolveCreatedAssetProofSourceExtendsCompactPath(t *testing.T) { + t.Parallel() + + committed, expectedRef, expectedRoot := proofSourceCommitResult(t) + base := committed.inputs[0].proofSource.blob + path := &tapsdk.AssetProofPath{ + Version: tapsdk.AssetProofPathVersionV0, + ConfirmedBaseProof: append([]byte(nil), base...), + } + encoded, err := path.MarshalBinary() + require.NoError(t, err) + committed.inputs[0].proofSource.kind = + tapsdk.CustomAnchorProofSourceCompactPath + committed.inputs[0].proofSource.blob = encoded + + resolved, err := resolveCreatedAssetProofSource( + committed, committed.outputs[0].anchorOutpoint, + committed.outputs[0].anchorValueSat, expectedRef, + committed.outputs[0].amount, tapsdk.Hash(expectedRoot), + ) + require.NoError(t, err) + require.Equal(t, ProofSourceCompactPath, resolved.ProofSourceKind) + var extended tapsdk.AssetProofPath + require.NoError( + t, extended.UnmarshalBinary( + resolved.CompactProofPath, + ), + ) + require.Equal(t, base, extended.ConfirmedBaseProof) + require.Len(t, extended.Steps, 1) +} + +// TestResolveCreatedAssetProofSourceRejectsMismatches pins the output, +// predecessor, script-mode, and compact-path ambiguity checks. +func TestResolveCreatedAssetProofSourceRejectsMismatches(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + mutate func(*commitResult, *tapsdk.Outpoint, *int64, + *tapsdk.AssetRef, *uint64, *chainhash.Hash) + wantErr string + }{ + { + name: "outpoint", + mutate: func(_ *commitResult, outpoint *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + outpoint.Index++ + }, + wantErr: "does not create", + }, + { + name: "carrier value", + mutate: func(_ *commitResult, _ *tapsdk.Outpoint, + carrier *int64, _ *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + (*carrier)++ + }, + wantErr: "does not create", + }, + { + name: "asset ref", + mutate: func(_ *commitResult, _ *tapsdk.Outpoint, + _ *int64, ref *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + *ref = tapsdk.AssetRefFromAssetID( + tapsdk.AssetID{99}, + ) + }, + wantErr: "does not create", + }, + { + name: "amount", + mutate: func(_ *commitResult, _ *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, amount *uint64, + _ *chainhash.Hash) { + + (*amount)++ + }, + wantErr: "does not create", + }, + { + name: "root", + mutate: func(_ *commitResult, _ *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, _ *uint64, + root *chainhash.Hash) { + + root[0] ^= 1 + }, + wantErr: "does not create", + }, + { + name: "non op true", + mutate: func(result *commitResult, _ *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + result.outputs[0].scriptMode = + tapsdk.CustomAssetScriptExternal + }, + wantErr: "not spendable through OP_TRUE", + }, + { + name: "missing predecessor", + mutate: func(result *commitResult, _ *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + result.inputs = nil + }, + wantErr: "predecessor is not present", + }, + { + name: "ambiguous predecessor", + mutate: func(result *commitResult, _ *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + result.inputs = append( + result.inputs, result.inputs[0], + ) + }, + wantErr: "multiple possible predecessor", + }, + { + name: "malformed transition", + mutate: func(result *commitResult, _ *tapsdk.Outpoint, + _ *int64, _ *tapsdk.AssetRef, _ *uint64, + _ *chainhash.Hash) { + + result.outputs[0].proofBlob = []byte( + "bad-proof", + ) + }, + wantErr: "summarize created asset proof", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + committed, ref, root := proofSourceCommitResult(t) + outpoint := committed.outputs[0].anchorOutpoint + carrier := committed.outputs[0].anchorValueSat + amount := committed.outputs[0].amount + test.mutate( + committed, &outpoint, &carrier, &ref, &amount, + &root, + ) + _, err := resolveCreatedAssetProofSource( + committed, outpoint, carrier, ref, amount, + tapsdk.Hash(root), + ) + require.ErrorContains(t, err, test.wantErr) + }) + } +} + +// TestResolveCreatedAssetProofSourceRejectsDepthExhaustion proves restart +// reconstruction cannot grow a compact path beyond the SDK's bounded depth. +func TestResolveCreatedAssetProofSourceRejectsDepthExhaustion(t *testing.T) { + t.Parallel() + + committed, ref, root := proofSourceCommitResult(t) + path := &tapsdk.AssetProofPath{ + Version: tapsdk.AssetProofPathVersionV0, + ConfirmedBaseProof: append( + []byte(nil), committed.inputs[0].proofSource.blob..., + ), + Steps: make( + []tapsdk.AssetProofPathStep, + tapsdk.AssetProofPathMaxDepth, + ), + } + for idx := range path.Steps { + path.Steps[idx].TransitionProof = append( + []byte(nil), committed.outputs[0].proofBlob..., + ) + } + encoded, err := path.MarshalBinary() + require.NoError(t, err) + committed.inputs[0].proofSource.kind = + tapsdk.CustomAnchorProofSourceCompactPath + committed.inputs[0].proofSource.blob = encoded + + _, err = resolveCreatedAssetProofSource( + committed, committed.outputs[0].anchorOutpoint, + committed.outputs[0].anchorValueSat, ref, + committed.outputs[0].amount, tapsdk.Hash(root), + ) + require.ErrorContains(t, err, "path depth") +} + +func proofSourceCommitResult(t *testing.T) (*commitResult, tapsdk.AssetRef, + chainhash.Hash) { + + t.Helper() + baseFile, baseProof, senderKey := proofSourceBase(t) + transition := proofSourceTransition( + t, baseProof, senderKey, testPrivateKey(t, 31), + ) + transitionBytes, err := transition.Bytes() + require.NoError(t, err) + step := tapsdk.AssetProofPathStep{ + TransitionProof: transitionBytes, + } + summary, err := step.Summary() + require.NoError(t, err) + root := chainhash.Hash{9, 8, 7} + + return &commitResult{ + inputs: []commitInput{{ + logicalInputID: "input-0", + logicalInputIndex: 3, + packetIndex: 1, + packetRole: tapsdk.CustomAnchorPacketRoleActive, + virtualInputIndex: 2, + anchorInputIndex: 0, + anchorOutpoint: summary.PreviousAnchorOutpoint, + assetRef: summary.AssetRef, + issuanceID: summary.IssuanceID, + amount: baseProof.Asset.Amount, + proofSource: commitProofSource{ + kind: tapsdk. + CustomAnchorProofSourceConfirmedFile, + blob: append([]byte(nil), baseFile...), + }, + }}, + outputs: []commitOutput{{ + logicalOutputID: "output-0", + logicalOutputIndex: 4, + packetIndex: 1, + packetRole: tapsdk.CustomAnchorPacketRoleActive, + virtualOutputIndex: 5, + anchorOutputIndex: summary.AnchorOutpoint.Index, + anchorOutpoint: summary.AnchorOutpoint, + anchorValueSat: summary.AnchorValueSat, + assetRef: summary.AssetRef, + issuanceID: summary.IssuanceID, + amount: summary.Amount, + taprootAssetRoot: tapsdk.Hash(root), + scriptKey: summary.ScriptKey, + scriptMode: tapsdk.CustomAssetScriptOPTrue, + opTrueWitness: [][]byte{ + { + txscript.OP_TRUE, + }, { + 1, + 2, + 3, + }, + }, + proofBlob: append([]byte(nil), transitionBytes...), + }}, + }, summary.AssetRef, root +} + +func proofSourceBase(t *testing.T) ([]byte, *proof.Proof, *btcec.PrivateKey) { + t.Helper() + senderKey := testPrivateKey(t, 29) + internalKey := testPrivateKey(t, 30) + genesis := asset.Genesis{ + FirstPrevOut: wire.OutPoint{ + Hash: chainhash.Hash{ + 1, + }, + Index: 1, + }, + Tag: "wavelength-proof-source", + OutputIndex: 0, + Type: asset.Normal, + } + amount := uint64(100) + version := commitment.TapCommitmentV2 + tapCommitment, assets, err := commitment.Mint( + &version, genesis, nil, &commitment.AssetDetails{ + Version: asset.V1, + Type: asset.Normal, + ScriptKey: keychain.KeyDescriptor{ + PubKey: senderKey.PubKey(), + }, + Amount: &amount, + }, + ) + require.NoError(t, err) + anchorTx := proofSourceAnchorTx( + t, genesis.FirstPrevOut, internalKey.PubKey(), tapCommitment, + ) + proofs, err := proof.NewMintingBlobs( + &proof.MintParams{ + BaseProofParams: proof.BaseProofParams{ + Block: proofSourceBlock(anchorTx), + BlockHeight: 100, + Tx: anchorTx, + TxIndex: 0, + OutputIndex: 0, + InternalKey: internalKey.PubKey(), + TaprootAssetRoot: tapCommitment, + }, + GenesisPoint: genesis.FirstPrevOut, + }, proof.MockVerifierCtx, + proof.WithGenOption(proof.WithVersion(proof.TransitionV1)), + ) + require.NoError(t, err) + baseProof := proofs[asset.ToSerialized(assets[0].ScriptKey.PubKey)] + require.NotNil(t, baseProof) + baseFile, err := proof.EncodeAsProofFile(baseProof) + require.NoError(t, err) + + return baseFile, baseProof, senderKey +} + +func proofSourceTransition(t *testing.T, previous *proof.Proof, + spendKey, recipientKey *btcec.PrivateKey) *proof.Proof { + + t.Helper() + newAsset := previous.Asset.Copy() + newAsset.ScriptKey = asset.NewScriptKeyBip86(keychain.KeyDescriptor{ + PubKey: recipientKey.PubKey(), + }) + previousID := &asset.PrevID{ + OutPoint: previous.OutPoint(), + ID: previous.Asset.ID(), + ScriptKey: asset.ToSerialized( + previous.Asset.ScriptKey.PubKey, + ), + } + newAsset.PrevWitnesses = []asset.Witness{{PrevID: previousID}} + inputs := commitment.InputSet{*previousID: &previous.Asset} + virtualTx, _, err := tapscript.VirtualTx(newAsset, inputs) + require.NoError(t, err) + virtualTx = asset.VirtualTxWithInput(virtualTx, 0, 0, 0, nil) + sigHash, err := tapscript.InputKeySpendSigHash( + virtualTx, &previous.Asset, newAsset, 0, + txscript.SigHashDefault, + ) + require.NoError(t, err) + tweakedSpendKey := txscript.TweakTaprootPrivKey(*spendKey, nil) + signingKey := spendKey + if bytes.Equal( + schnorr.SerializePubKey( + tweakedSpendKey.PubKey(), + ), + schnorr.SerializePubKey(previous.Asset.ScriptKey.PubKey), + ) { + + signingKey = tweakedSpendKey + } + signature, err := schnorr.Sign(signingKey, sigHash) + require.NoError(t, err) + newAsset.PrevWitnesses[0].TxWitness = wire.TxWitness{ + signature.Serialize(), + } + + assetCommitment, err := commitment.NewAssetCommitment(newAsset) + require.NoError(t, err) + version := commitment.TapCommitmentV2 + tapCommitment, err := commitment.NewTapCommitment( + &version, assetCommitment, + ) + require.NoError(t, err) + spentAsset, err := asset.MakeSpentAsset(newAsset.PrevWitnesses[0]) + require.NoError(t, err) + require.NoError( + t, + tapCommitment.MergeAltLeaves( + asset.ToAltLeaves( + []*asset.Asset{spentAsset}, + ), + ), + ) + anchorTx := proofSourceAnchorTx( + t, previous.OutPoint(), recipientKey.PubKey(), tapCommitment, + ) + transition, err := proof.CreateTransitionProof( + previous.OutPoint(), &proof.TransitionParams{ + BaseProofParams: proof.BaseProofParams{ + Block: proofSourceBlock(anchorTx), + Tx: anchorTx, + TxIndex: 0, + OutputIndex: 0, + InternalKey: recipientKey.PubKey(), + TaprootAssetRoot: tapCommitment, + }, + NewAsset: newAsset, + }, proof.WithVersion(proof.TransitionV1), + ) + require.NoError(t, err) + + return transition +} + +func proofSourceAnchorTx(t *testing.T, previous wire.OutPoint, + internalKey *btcec.PublicKey, + tapCommitment *commitment.TapCommitment) *wire.MsgTx { + + t.Helper() + root := tapCommitment.TapscriptRoot(nil) + outputKey := txscript.ComputeTaprootOutputKey(internalKey, root[:]) + pkScript, err := txscript.PayToTaprootScript(outputKey) + require.NoError(t, err) + + return &wire.MsgTx{ + Version: 3, + TxIn: []*wire.TxIn{{ + PreviousOutPoint: previous, + }}, + TxOut: []*wire.TxOut{{ + Value: 330, + PkScript: pkScript, + }}, + } +} + +func proofSourceBlock(anchorTx *wire.MsgTx) *wire.MsgBlock { + tree := blockchain.BuildMerkleTreeStore( + []*btcutil.Tx{btcutil.NewTx(anchorTx)}, false, + ) + + return &wire.MsgBlock{ + Header: wire.BlockHeader{ + MerkleRoot: *tree[len(tree)-1], + }, + Transactions: []*wire.MsgTx{ + anchorTx, + }, + } +} diff --git a/vtxo/incoming_handler.go b/vtxo/incoming_handler.go index 360c7672a..9b6328813 100644 --- a/vtxo/incoming_handler.go +++ b/vtxo/incoming_handler.go @@ -1,6 +1,7 @@ package vtxo import ( + "bytes" "context" "database/sql" "errors" @@ -313,19 +314,44 @@ func (h *IncomingVTXOHandler) Receive(ctx context.Context, return fn.Ok[IncomingVTXOResp](nil) } + assetRoot, assetRef, assetAmount, err := + incomingTaprootAssetMetadata(evt) + if err != nil { + h.log.WarnS(ctx, "Invalid incoming Taproot Asset metadata", + err, + slog.String("outpoint", outpoint.String()), + ) + + return fn.Ok[IncomingVTXOResp](nil) + } + desc := &Descriptor{ - Outpoint: outpoint, - Amount: btcutil.Amount(evt.ValueSat), - PolicyTemplate: policyTemplate, - PkScript: pkScript, - ClientKey: rec.ClientKey, - OperatorKey: operatorKey, - TapScript: tapscript, - RoundID: evt.RoundId, - CommitmentTxID: commitTxID, - BatchExpiry: evt.BatchExpiryHeight, - RelativeExpiry: evt.RelativeExpiry, - Status: VTXOStatusLive, + Outpoint: outpoint, + Amount: btcutil.Amount(evt.ValueSat), + PolicyTemplate: policyTemplate, + PkScript: pkScript, + TaprootAssetRoot: assetRoot, + TaprootAssetRef: assetRef, + TaprootAssetAmount: assetAmount, + ClientKey: rec.ClientKey, + OperatorKey: operatorKey, + TapScript: tapscript, + RoundID: evt.RoundId, + CommitmentTxID: commitTxID, + BatchExpiry: evt.BatchExpiryHeight, + RelativeExpiry: evt.RelativeExpiry, + Status: VTXOStatusLive, + } + if assetRoot != nil { + err := validateIncomingAssetScript(desc, pkScript) + if err != nil { + h.log.WarnS(ctx, "Incoming asset metadata does not bind "+ + "the VTXO script", err, + slog.String("outpoint", outpoint.String()), + ) + + return fn.Ok[IncomingVTXOResp](nil) + } } // Resolve ancestry before persisting so the descriptor lands @@ -339,22 +365,9 @@ func (h *IncomingVTXOHandler) Receive(ctx context.Context, // Fetch failures are warn-logged but do not block // materialization, since the receive must still succeed for // cooperative use. - if h.cfg.AncestryFetcher != nil { - extras, err := h.cfg.AncestryFetcher( - ctx, outpoint, pkScript, rec.ClientKey, - ) - if err != nil { - h.log.WarnS(ctx, "Failed to fetch incoming VTXO "+ - "ancestry; persisting without — unilateral "+ - "exit will be unavailable until backfill", - err, - slog.String("outpoint", outpoint.String()), - ) - } else { - desc.Ancestry = extras.Ancestry - desc.CreatedHeight = extras.CreatedHeight - } - } + h.hydrateIncomingAncestry( + ctx, desc, outpoint, pkScript, rec.ClientKey, + ) // Persist the VTXO. A save failure signals a database or // schema inconsistency that must be surfaced. @@ -400,3 +413,78 @@ func (h *IncomingVTXOHandler) Receive(ctx context.Context, return fn.Ok[IncomingVTXOResp](nil) } + +func (h *IncomingVTXOHandler) hydrateIncomingAncestry(ctx context.Context, + desc *Descriptor, outpoint wire.OutPoint, pkScript []byte, + clientKey keychain.KeyDescriptor) { + + if h.cfg.AncestryFetcher == nil { + return + } + + extras, err := h.cfg.AncestryFetcher( + ctx, outpoint, pkScript, clientKey, + ) + if err != nil { + h.log.WarnS(ctx, "Failed to fetch incoming VTXO "+ + "ancestry; persisting without — unilateral "+ + "exit will be unavailable until backfill", + err, + slog.String("outpoint", outpoint.String()), + ) + + return + } + + desc.Ancestry = extras.Ancestry + desc.CreatedHeight = extras.CreatedHeight +} + +func validateIncomingAssetScript(desc *Descriptor, pkScript []byte) error { + expectedPkScript, err := desc.EffectivePkScript() + if err != nil { + return err + } + if !bytes.Equal(expectedPkScript, pkScript) { + return fmt.Errorf("composed asset script mismatch") + } + + return nil +} + +// incomingTaprootAssetMetadata decodes the optional asset fields on a round +// receive event. Historical root-only events remain valid, while new identity +// and amount fields must appear together. +func incomingTaprootAssetMetadata(evt *arkrpc.IncomingVTXOEvent) ( + *chainhash.Hash, string, uint64, error) { + + rootRaw := evt.GetTaprootAssetRoot() + assetRef := evt.GetTaprootAssetRef() + assetAmount := evt.GetTaprootAssetAmount() + if len(rootRaw) == 0 { + if assetRef != "" || assetAmount != 0 { + return nil, "", 0, fmt.Errorf("asset metadata has no " + + "commitment root") + } + + return nil, "", 0, nil + } + + root, err := chainhash.NewHash(rootRaw) + if err != nil { + return nil, "", 0, fmt.Errorf("parse commitment root: %w", err) + } + if assetRef == "" && assetAmount == 0 { + return root, "", 0, nil + } + if assetRef == "" || assetAmount == 0 { + return nil, "", 0, fmt.Errorf("asset ref and amount must " + + "both be provided") + } + if len(assetRef) > MaxTaprootAssetRefBytes { + return nil, "", 0, fmt.Errorf("asset ref exceeds %d bytes", + MaxTaprootAssetRefBytes) + } + + return root, assetRef, assetAmount, nil +} diff --git a/vtxo/incoming_handler_test.go b/vtxo/incoming_handler_test.go index da3b21ed1..ecf1a0263 100644 --- a/vtxo/incoming_handler_test.go +++ b/vtxo/incoming_handler_test.go @@ -7,7 +7,9 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chainhash/v2" + "github.com/btcsuite/btcd/txscript/v2" "github.com/lightninglabs/wavelength/arkrpc" + "github.com/lightninglabs/wavelength/lib/arkscript" "github.com/lightningnetwork/lnd/keychain" "github.com/stretchr/testify/require" ) @@ -116,6 +118,61 @@ func TestIncomingVTXOHandlerOwnedScript(t *testing.T) { require.Equal(t, VTXOStatusLive, desc.Status) } +// TestIncomingVTXOHandlerAssetMetadata verifies the generic indexer event +// path materializes the SDK-neutral identity and amount while retaining the +// event value as the independent carrier-satoshi amount. +func TestIncomingVTXOHandlerAssetMetadata(t *testing.T) { + t.Parallel() + + owner, err := btcec.NewPrivateKey() + require.NoError(t, err) + operator, err := btcec.NewPrivateKey() + require.NoError(t, err) + root := chainhash.Hash{9, 8, 7} + policy, err := arkscript.NewVTXOPolicy( + owner.PubKey(), operator.PubKey(), 144, + ) + require.NoError(t, err) + composed, err := arkscript.ComposeWithSiblingRoot( + policy.CompiledPolicy, root, + ) + require.NoError(t, err) + pkScript, err := txscript.PayToTaprootScript(composed.OutputKey()) + require.NoError(t, err) + + lookup := &mockScriptLookup{scripts: map[string]*OwnedReceiveScript{ + string(pkScript): { + ClientKey: keychain.KeyDescriptor{ + PubKey: owner.PubKey(), + }, + OperatorPubKey: operator.PubKey(), + ExitDelay: 144, + }, + }} + saver := &mockVTXOSaver{} + handler := NewIncomingVTXOHandler(IncomingVTXOHandlerConfig{ + ScriptStore: lookup, + VTXOStore: saver, + }) + txid := chainhash.Hash{1} + evt := newTestEvent(txid, 0, pkScript, 1_000, "asset-round") + evt.TaprootAssetRoot = root[:] + evt.TaprootAssetRef = "asset-id:010203" + evt.TaprootAssetAmount = 800 + + _, resultErr := handler.Receive( + t.Context(), IncomingVTXOMsg{Event: evt}, + ).Unpack() + require.NoError(t, resultErr) + require.Len(t, saver.saved, 1) + require.Equal(t, int64(1_000), int64(saver.saved[0].Amount)) + require.Equal(t, &root, saver.saved[0].TaprootAssetRoot) + require.Equal(t, "asset-id:010203", + saver.saved[0].TaprootAssetRef) + require.Equal(t, uint64(800), + saver.saved[0].TaprootAssetAmount) +} + // TestIncomingVTXOHandlerUnownedScript verifies that a VTXO_CREATED // event for an unowned script is silently ignored. func TestIncomingVTXOHandlerUnownedScript(t *testing.T) { diff --git a/vtxo/interfaces.go b/vtxo/interfaces.go index 816dc4662..b7c8854ab 100644 --- a/vtxo/interfaces.go +++ b/vtxo/interfaces.go @@ -18,6 +18,12 @@ import ( "github.com/lightningnetwork/lnd/keychain" ) +const ( + // MaxTaprootAssetRefBytes bounds the opaque SDK-level asset identity at + // every Wavelength persistence and wire boundary. + MaxTaprootAssetRefBytes = 512 +) + // ============================================================================= // MESSAGE SPEC // ============================================================================= @@ -358,6 +364,15 @@ type Descriptor struct { // must include this root as the final control-block sibling. TaprootAssetRoot *chainhash.Hash + // TaprootAssetRef is the opaque tap-sdk asset identity carried by this + // VTXO. It is intentionally a string so the wallet domain does not + // depend on tap-sdk or taproot-assets types. + TaprootAssetRef string + + // TaprootAssetAmount is the number of Taproot Asset units carried by + // this VTXO. Amount remains the separate Bitcoin carrier value. + TaprootAssetAmount uint64 + // ClientKey is the client's key descriptor for this VTXO. ClientKey keychain.KeyDescriptor diff --git a/waved/rpc_server.go b/waved/rpc_server.go index f89d84d24..abbbfe249 100644 --- a/waved/rpc_server.go +++ b/waved/rpc_server.go @@ -1425,6 +1425,13 @@ func descriptorToProto(v *vtxo.Descriptor) *waverpc.VTXO { CommitmentTxid: v.CommitmentTxID.String(), ChainDepth: uint32(v.ChainDepth), } + if v.TaprootAssetRoot != nil { + proto.TaprootAsset = &waverpc.VTXOTaprootAsset{ + AssetRef: v.TaprootAssetRef, + Amount: v.TaprootAssetAmount, + CommitmentRoot: v.TaprootAssetRoot.CloneBytes(), + } + } // Settlement is Some only for FORFEITED VTXOs whose forfeit round row // was found by the by-status join; for every other VTXO it is None and diff --git a/waved/rpc_swap_lookup.go b/waved/rpc_swap_lookup.go index a4599661b..3f543fe92 100644 --- a/waved/rpc_swap_lookup.go +++ b/waved/rpc_swap_lookup.go @@ -214,8 +214,13 @@ func indexedVTXOToProto(vtxo *arkrpc.VTXO, currentHeight int32, spentByTxid = spentHash.String() } + assetRoot, assetRef, assetAmount, err := + indexerTaprootAssetMetadata(vtxo) + if err != nil { + return nil, err + } - return &waverpc.VTXO{ + result := &waverpc.VTXO{ Outpoint: fmt.Sprintf("%s:%d", txid, outpoint.GetVout()), AmountSat: int64(vtxo.GetValueSat()), Status: status, @@ -233,7 +238,16 @@ func indexedVTXOToProto(vtxo *arkrpc.VTXO, currentHeight int32, ExpiryInfo: expiryInfoFromIndexedVTXO( vtxo, currentHeight, cfg, ), - }, nil + } + if assetRoot != nil { + result.TaprootAsset = &waverpc.VTXOTaprootAsset{ + AssetRef: assetRef, + Amount: assetAmount, + CommitmentRoot: assetRoot.CloneBytes(), + } + } + + return result, nil } // indexerStatusToDaemonStatus converts arkrpc VTXO status enums to waverpc. diff --git a/waved/rpc_taproot_asset_onboarding.go b/waved/rpc_taproot_asset_onboarding.go index d800e82cb..46b72a52c 100644 --- a/waved/rpc_taproot_asset_onboarding.go +++ b/waved/rpc_taproot_asset_onboarding.go @@ -270,6 +270,8 @@ func (s *Server) registerTaprootAssetOnboarding(ctx context.Context, []byte(nil), registration.TaprootAssetRoot[:]..., ), + TaprootAssetRef: registration.TaprootAssetRef, + TaprootAssetAmount: registration.TaprootAssetAmount, }, ) if status.Code(err) == codes.FailedPrecondition { @@ -312,9 +314,13 @@ func (r *RPCServer) materializeTaprootAssetOnboarding(ctx context.Context, } root := result.TaprootAssetRoot desc := &vtxo.Descriptor{ - Outpoint: result.Outpoint, - Amount: btcutil.Amount(result.ValueSat), - PolicyTemplate: append([]byte(nil), result.PolicyTemplate...), + Outpoint: result.Outpoint, + Amount: btcutil.Amount(result.ValueSat), + TaprootAssetRef: result.AssetRef, + TaprootAssetAmount: result.AssetAmount, + PolicyTemplate: append( + []byte(nil), result.PolicyTemplate..., + ), PkScript: append([]byte(nil), result.PkScript...), TaprootAssetRoot: &root, ClientKey: result.OwnerKey, @@ -352,7 +358,10 @@ func (r *RPCServer) materializeTaprootAssetOnboarding(ctx context.Context, func sameOnboardedVTXO(left, right *vtxo.Descriptor) bool { if left == nil || right == nil || left.Outpoint != right.Outpoint || - left.Amount != right.Amount || left.TaprootAssetRoot == nil || + left.Amount != right.Amount || + left.TaprootAssetRef != right.TaprootAssetRef || + left.TaprootAssetAmount != right.TaprootAssetAmount || + left.TaprootAssetRoot == nil || right.TaprootAssetRoot == nil || *left.TaprootAssetRoot != *right.TaprootAssetRoot || left.RelativeExpiry != right.RelativeExpiry || diff --git a/waved/rpc_taproot_asset_onboarding_test.go b/waved/rpc_taproot_asset_onboarding_test.go index 2642ac2a6..117152123 100644 --- a/waved/rpc_taproot_asset_onboarding_test.go +++ b/waved/rpc_taproot_asset_onboarding_test.go @@ -58,13 +58,16 @@ func TestOnboardTaprootAssetPendingThenReady(t *testing.T) { PubKey: owner.PubKey(), } ready := &tapassets.OnboardingResult{ - Status: tapassets.OnboardingStatusReady, - Outpoint: outpoint, - ValueSat: 1_000, - ActualFeeSat: 125, - PolicyTemplate: policyBytes, - PkScript: pkScript, - TaprootAssetRoot: root, + Status: tapassets.OnboardingStatusReady, + Outpoint: outpoint, + ValueSat: 1_000, + ActualFeeSat: 125, + PolicyTemplate: policyBytes, + PkScript: pkScript, + TaprootAssetRoot: root, + AssetRef: "asset:00000000000000000000000000000000" + + "00000000000000000000000000000001", + AssetAmount: 21, OwnerKey: ownerKey, OperatorKey: operator.PubKey(), ExitDelay: 144, @@ -156,6 +159,8 @@ func TestOnboardTaprootAssetPendingThenReady(t *testing.T) { require.True(t, sameOnboardedVTXO(stored, <-materialized)) require.Empty(t, stored.Ancestry) require.Equal(t, txid, stored.CommitmentTxID) + require.Equal(t, ready.AssetRef, stored.TaprootAssetRef) + require.Equal(t, ready.AssetAmount, stored.TaprootAssetAmount) response, err = rpcServer.OnboardTaprootAsset(t.Context(), request) require.NoError(t, err) @@ -289,6 +294,8 @@ func TestRegisterTaprootAssetOnboarding(t *testing.T) { []byte("registration-root"), ), ), + TaprootAssetRef: "asset-id:010203", + TaprootAssetAmount: 21, } _, err := server.registerTaprootAssetOnboarding( t.Context(), registration, diff --git a/waved/rpc_vtxo_settlement_test.go b/waved/rpc_vtxo_settlement_test.go index 92dc5877f..2523c6ec4 100644 --- a/waved/rpc_vtxo_settlement_test.go +++ b/waved/rpc_vtxo_settlement_test.go @@ -68,3 +68,58 @@ func TestDescriptorToProtoSettlement(t *testing.T) { require.Nil(t, got.GetSettlement()) }) } + +// TestDescriptorToProtoTaprootAsset separates the Bitcoin carrier value from +// the nested SDK-neutral asset quantity and keeps ordinary VTXOs free of an +// asset sub-message. +func TestDescriptorToProtoTaprootAsset(t *testing.T) { + t.Parallel() + + const carrierSats = 546 + root := chainhash.HashH([]byte("vtxo-asset-root")) + desc := &vtxo.Descriptor{ + Outpoint: wire.OutPoint{ + Hash: chainhash.HashH([]byte("asset-vtxo")), + Index: 2, + }, + Amount: carrierSats, + Status: vtxo.VTXOStatusLive, + TaprootAssetRoot: &root, + TaprootAssetRef: "asset:rpc-projection", + TaprootAssetAmount: ^uint64(0), + } + + got := descriptorToProto(desc) + require.EqualValues(t, carrierSats, got.GetAmountSat()) + require.NotNil(t, got.GetTaprootAsset()) + require.Equal( + t, desc.TaprootAssetRef, got.GetTaprootAsset().GetAssetRef(), + ) + require.Equal( + t, desc.TaprootAssetAmount, got.GetTaprootAsset().GetAmount(), + ) + require.Equal( + t, root.CloneBytes(), got.GetTaprootAsset().GetCommitmentRoot(), + ) + + ordinary := &vtxo.Descriptor{ + Outpoint: wire.OutPoint{ + Hash: chainhash.HashH([]byte("bitcoin-vtxo")), + }, + Amount: carrierSats, + Status: vtxo.VTXOStatusLive, + } + require.Nil(t, descriptorToProto(ordinary).GetTaprootAsset()) + + // Historical rows written before semantic asset metadata existed still + // expose their commitment root without inventing an identity or amount. + legacy := &vtxo.Descriptor{ + Amount: carrierSats, + TaprootAssetRoot: &root, + } + legacyAsset := descriptorToProto(legacy).GetTaprootAsset() + require.NotNil(t, legacyAsset) + require.Empty(t, legacyAsset.GetAssetRef()) + require.Zero(t, legacyAsset.GetAmount()) + require.Equal(t, root.CloneBytes(), legacyAsset.GetCommitmentRoot()) +} diff --git a/waved/taproot_asset_metadata.go b/waved/taproot_asset_metadata.go new file mode 100644 index 000000000..b9a3a1ab4 --- /dev/null +++ b/waved/taproot_asset_metadata.go @@ -0,0 +1,51 @@ +package waved + +import ( + "fmt" + + "github.com/btcsuite/btcd/chainhash/v2" + "github.com/lightninglabs/wavelength/arkrpc" + "github.com/lightninglabs/wavelength/vtxo" +) + +// indexerTaprootAssetMetadata decodes the optional SDK-neutral asset metadata +// carried by an indexer VTXO. Root-only rows remain valid for compatibility; +// any new identity/amount pair must be complete. +func indexerTaprootAssetMetadata(indexed *arkrpc.VTXO) (*chainhash.Hash, string, + uint64, error) { + + if indexed == nil { + return nil, "", 0, fmt.Errorf("indexer vtxo must be provided") + } + + rootRaw := indexed.GetTaprootAssetRoot() + assetRef := indexed.GetTaprootAssetRef() + assetAmount := indexed.GetTaprootAssetAmount() + if len(rootRaw) == 0 { + if assetRef != "" || assetAmount != 0 { + return nil, "", 0, fmt.Errorf("indexer Taproot Asset " + + "metadata has no commitment root") + } + + return nil, "", 0, nil + } + + root, err := chainhash.NewHash(rootRaw) + if err != nil { + return nil, "", 0, fmt.Errorf("parse indexer Taproot Asset "+ + "root: %w", err) + } + if assetRef == "" && assetAmount == 0 { + return root, "", 0, nil + } + if assetRef == "" || assetAmount == 0 { + return nil, "", 0, fmt.Errorf("indexer Taproot Asset ref and " + + "amount must both be provided") + } + if len(assetRef) > vtxo.MaxTaprootAssetRefBytes { + return nil, "", 0, fmt.Errorf("indexer Taproot Asset ref "+ + "exceeds %d bytes", vtxo.MaxTaprootAssetRefBytes) + } + + return root, assetRef, assetAmount, nil +} diff --git a/waved/wallet_recovery.go b/waved/wallet_recovery.go index 9793aaee2..7e6c7fc38 100644 --- a/waved/wallet_recovery.go +++ b/waved/wallet_recovery.go @@ -404,23 +404,33 @@ func recoveryDescriptorFromIndexer(indexed *arkrpc.VTXO, if err != nil { return nil, false, fmt.Errorf("parse commitment txid: %w", err) } + assetRoot, assetRef, assetAmount, err := + indexerTaprootAssetMetadata(indexed) + if err != nil { + return nil, false, err + } return &vtxo.Descriptor{ Outpoint: outpoint, Amount: btcutil.Amount(indexed.GetValueSat()), PolicyTemplate: policyTemplate, - PkScript: append([]byte(nil), indexed.GetPkScript()...), - ClientKey: keyDesc, - OperatorKey: operatorKey, - TapScript: tapscript, - Ancestry: ancestry, - RoundID: indexed.GetRoundId(), - CommitmentTxID: *commitmentTxID, - BatchExpiry: indexed.GetBatchExpiryHeight(), - RelativeExpiry: exitDelay, - ChainDepth: int(indexed.GetChainDepth()), - CreatedHeight: indexed.GetCreatedHeight(), - Status: status, + PkScript: append( + []byte(nil), indexed.GetPkScript()..., + ), + TaprootAssetRoot: assetRoot, + TaprootAssetRef: assetRef, + TaprootAssetAmount: assetAmount, + ClientKey: keyDesc, + OperatorKey: operatorKey, + TapScript: tapscript, + Ancestry: ancestry, + RoundID: indexed.GetRoundId(), + CommitmentTxID: *commitmentTxID, + BatchExpiry: indexed.GetBatchExpiryHeight(), + RelativeExpiry: exitDelay, + ChainDepth: int(indexed.GetChainDepth()), + CreatedHeight: indexed.GetCreatedHeight(), + Status: status, // Thread the operator's stamped construction version onto the // recovered descriptor so both sides agree on the rules this diff --git a/waverpc/daemon.pb.go b/waverpc/daemon.pb.go index df6a17995..762265e0f 100644 --- a/waverpc/daemon.pb.go +++ b/waverpc/daemon.pb.go @@ -2195,7 +2195,10 @@ type VTXO struct { // commitment tx of the leave/cooperative-forfeit round). It is present // only for FORFEITED VTXOs whose forfeit round is known, and unset // otherwise, so absence is explicit rather than a zero-value sentinel. - Settlement *VTXOSettlement `protobuf:"bytes,14,opt,name=settlement,proto3" json:"settlement,omitempty"` + Settlement *VTXOSettlement `protobuf:"bytes,14,opt,name=settlement,proto3" json:"settlement,omitempty"` + // taproot_asset is present when this VTXO carries a Taproot Asset. + // amount_sat above remains the separate Bitcoin carrier value. + TaprootAsset *VTXOTaprootAsset `protobuf:"bytes,15,opt,name=taproot_asset,json=taprootAsset,proto3" json:"taproot_asset,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2328,6 +2331,78 @@ func (x *VTXO) GetSettlement() *VTXOSettlement { return nil } +func (x *VTXO) GetTaprootAsset() *VTXOTaprootAsset { + if x != nil { + return x.TaprootAsset + } + return nil +} + +// VTXOTaprootAsset is SDK-neutral asset metadata attached to one VTXO. +type VTXOTaprootAsset struct { + state protoimpl.MessageState `protogen:"open.v1"` + // asset_ref is the opaque tap-sdk asset identity. + AssetRef string `protobuf:"bytes,1,opt,name=asset_ref,json=assetRef,proto3" json:"asset_ref,omitempty"` + // amount is the number of Taproot Asset units carried by the VTXO. + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount,omitempty"` + // commitment_root is the 32-byte Taproot Asset commitment root composed + // beside the VTXO's semantic Ark policy. + CommitmentRoot []byte `protobuf:"bytes,3,opt,name=commitment_root,json=commitmentRoot,proto3" json:"commitment_root,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *VTXOTaprootAsset) Reset() { + *x = VTXOTaprootAsset{} + mi := &file_daemon_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *VTXOTaprootAsset) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VTXOTaprootAsset) ProtoMessage() {} + +func (x *VTXOTaprootAsset) ProtoReflect() protoreflect.Message { + mi := &file_daemon_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VTXOTaprootAsset.ProtoReflect.Descriptor instead. +func (*VTXOTaprootAsset) Descriptor() ([]byte, []int) { + return file_daemon_proto_rawDescGZIP(), []int{15} +} + +func (x *VTXOTaprootAsset) GetAssetRef() string { + if x != nil { + return x.AssetRef + } + return "" +} + +func (x *VTXOTaprootAsset) GetAmount() uint64 { + if x != nil { + return x.Amount + } + return 0 +} + +func (x *VTXOTaprootAsset) GetCommitmentRoot() []byte { + if x != nil { + return x.CommitmentRoot + } + return nil +} + type VTXOSettlement struct { state protoimpl.MessageState `protogen:"open.v1"` // txid is the hex-encoded txid of the round commitment tx that forfeited @@ -2347,7 +2422,7 @@ type VTXOSettlement struct { func (x *VTXOSettlement) Reset() { *x = VTXOSettlement{} - mi := &file_daemon_proto_msgTypes[15] + mi := &file_daemon_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2359,7 +2434,7 @@ func (x *VTXOSettlement) String() string { func (*VTXOSettlement) ProtoMessage() {} func (x *VTXOSettlement) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[15] + mi := &file_daemon_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2372,7 +2447,7 @@ func (x *VTXOSettlement) ProtoReflect() protoreflect.Message { // Deprecated: Use VTXOSettlement.ProtoReflect.Descriptor instead. func (*VTXOSettlement) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{15} + return file_daemon_proto_rawDescGZIP(), []int{16} } func (x *VTXOSettlement) GetTxid() string { @@ -2415,7 +2490,7 @@ type ListVTXOsRequest struct { func (x *ListVTXOsRequest) Reset() { *x = ListVTXOsRequest{} - mi := &file_daemon_proto_msgTypes[16] + mi := &file_daemon_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2427,7 +2502,7 @@ func (x *ListVTXOsRequest) String() string { func (*ListVTXOsRequest) ProtoMessage() {} func (x *ListVTXOsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[16] + mi := &file_daemon_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2440,7 +2515,7 @@ func (x *ListVTXOsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListVTXOsRequest.ProtoReflect.Descriptor instead. func (*ListVTXOsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{16} + return file_daemon_proto_rawDescGZIP(), []int{17} } func (x *ListVTXOsRequest) GetStatusFilter() VTXOStatus { @@ -2474,7 +2549,7 @@ type ListVTXOsResponse struct { func (x *ListVTXOsResponse) Reset() { *x = ListVTXOsResponse{} - mi := &file_daemon_proto_msgTypes[17] + mi := &file_daemon_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2486,7 +2561,7 @@ func (x *ListVTXOsResponse) String() string { func (*ListVTXOsResponse) ProtoMessage() {} func (x *ListVTXOsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[17] + mi := &file_daemon_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2499,7 +2574,7 @@ func (x *ListVTXOsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListVTXOsResponse.ProtoReflect.Descriptor instead. func (*ListVTXOsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{17} + return file_daemon_proto_rawDescGZIP(), []int{18} } func (x *ListVTXOsResponse) GetVtxos() []*VTXO { @@ -2517,7 +2592,7 @@ type NewAddressRequest struct { func (x *NewAddressRequest) Reset() { *x = NewAddressRequest{} - mi := &file_daemon_proto_msgTypes[18] + mi := &file_daemon_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2529,7 +2604,7 @@ func (x *NewAddressRequest) String() string { func (*NewAddressRequest) ProtoMessage() {} func (x *NewAddressRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[18] + mi := &file_daemon_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2542,7 +2617,7 @@ func (x *NewAddressRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewAddressRequest.ProtoReflect.Descriptor instead. func (*NewAddressRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{18} + return file_daemon_proto_rawDescGZIP(), []int{19} } type NewAddressResponse struct { @@ -2555,7 +2630,7 @@ type NewAddressResponse struct { func (x *NewAddressResponse) Reset() { *x = NewAddressResponse{} - mi := &file_daemon_proto_msgTypes[19] + mi := &file_daemon_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2567,7 +2642,7 @@ func (x *NewAddressResponse) String() string { func (*NewAddressResponse) ProtoMessage() {} func (x *NewAddressResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[19] + mi := &file_daemon_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2580,7 +2655,7 @@ func (x *NewAddressResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use NewAddressResponse.ProtoReflect.Descriptor instead. func (*NewAddressResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{19} + return file_daemon_proto_rawDescGZIP(), []int{20} } func (x *NewAddressResponse) GetAddress() string { @@ -2601,7 +2676,7 @@ type NewReceiveScriptRequest struct { func (x *NewReceiveScriptRequest) Reset() { *x = NewReceiveScriptRequest{} - mi := &file_daemon_proto_msgTypes[20] + mi := &file_daemon_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2613,7 +2688,7 @@ func (x *NewReceiveScriptRequest) String() string { func (*NewReceiveScriptRequest) ProtoMessage() {} func (x *NewReceiveScriptRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[20] + mi := &file_daemon_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2626,7 +2701,7 @@ func (x *NewReceiveScriptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use NewReceiveScriptRequest.ProtoReflect.Descriptor instead. func (*NewReceiveScriptRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{20} + return file_daemon_proto_rawDescGZIP(), []int{21} } func (x *NewReceiveScriptRequest) GetLabel() string { @@ -2654,7 +2729,7 @@ type NewReceiveScriptResponse struct { func (x *NewReceiveScriptResponse) Reset() { *x = NewReceiveScriptResponse{} - mi := &file_daemon_proto_msgTypes[21] + mi := &file_daemon_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2666,7 +2741,7 @@ func (x *NewReceiveScriptResponse) String() string { func (*NewReceiveScriptResponse) ProtoMessage() {} func (x *NewReceiveScriptResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[21] + mi := &file_daemon_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2679,7 +2754,7 @@ func (x *NewReceiveScriptResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use NewReceiveScriptResponse.ProtoReflect.Descriptor instead. func (*NewReceiveScriptResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{21} + return file_daemon_proto_rawDescGZIP(), []int{22} } func (x *NewReceiveScriptResponse) GetPkScriptHex() string { @@ -2728,7 +2803,7 @@ type ReceiveAuthKeyRequest struct { func (x *ReceiveAuthKeyRequest) Reset() { *x = ReceiveAuthKeyRequest{} - mi := &file_daemon_proto_msgTypes[22] + mi := &file_daemon_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2740,7 +2815,7 @@ func (x *ReceiveAuthKeyRequest) String() string { func (*ReceiveAuthKeyRequest) ProtoMessage() {} func (x *ReceiveAuthKeyRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[22] + mi := &file_daemon_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2753,7 +2828,7 @@ func (x *ReceiveAuthKeyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiveAuthKeyRequest.ProtoReflect.Descriptor instead. func (*ReceiveAuthKeyRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{22} + return file_daemon_proto_rawDescGZIP(), []int{23} } func (x *ReceiveAuthKeyRequest) GetPaymentHash() []byte { @@ -2774,7 +2849,7 @@ type ReceiveAuthKeyResponse struct { func (x *ReceiveAuthKeyResponse) Reset() { *x = ReceiveAuthKeyResponse{} - mi := &file_daemon_proto_msgTypes[23] + mi := &file_daemon_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2786,7 +2861,7 @@ func (x *ReceiveAuthKeyResponse) String() string { func (*ReceiveAuthKeyResponse) ProtoMessage() {} func (x *ReceiveAuthKeyResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[23] + mi := &file_daemon_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2799,7 +2874,7 @@ func (x *ReceiveAuthKeyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiveAuthKeyResponse.ProtoReflect.Descriptor instead. func (*ReceiveAuthKeyResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{23} + return file_daemon_proto_rawDescGZIP(), []int{24} } func (x *ReceiveAuthKeyResponse) GetPubkey() []byte { @@ -2825,7 +2900,7 @@ type SignReceiveAuthMessageRequest struct { func (x *SignReceiveAuthMessageRequest) Reset() { *x = SignReceiveAuthMessageRequest{} - mi := &file_daemon_proto_msgTypes[24] + mi := &file_daemon_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2837,7 +2912,7 @@ func (x *SignReceiveAuthMessageRequest) String() string { func (*SignReceiveAuthMessageRequest) ProtoMessage() {} func (x *SignReceiveAuthMessageRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[24] + mi := &file_daemon_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2850,7 +2925,7 @@ func (x *SignReceiveAuthMessageRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignReceiveAuthMessageRequest.ProtoReflect.Descriptor instead. func (*SignReceiveAuthMessageRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{24} + return file_daemon_proto_rawDescGZIP(), []int{25} } func (x *SignReceiveAuthMessageRequest) GetPaymentHash() []byte { @@ -2884,7 +2959,7 @@ type SignReceiveAuthMessageResponse struct { func (x *SignReceiveAuthMessageResponse) Reset() { *x = SignReceiveAuthMessageResponse{} - mi := &file_daemon_proto_msgTypes[25] + mi := &file_daemon_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2896,7 +2971,7 @@ func (x *SignReceiveAuthMessageResponse) String() string { func (*SignReceiveAuthMessageResponse) ProtoMessage() {} func (x *SignReceiveAuthMessageResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[25] + mi := &file_daemon_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2909,7 +2984,7 @@ func (x *SignReceiveAuthMessageResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignReceiveAuthMessageResponse.ProtoReflect.Descriptor instead. func (*SignReceiveAuthMessageResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{25} + return file_daemon_proto_rawDescGZIP(), []int{26} } func (x *SignReceiveAuthMessageResponse) GetSignature() []byte { @@ -2935,7 +3010,7 @@ type SignReceiveAuthMessageCompactRequest struct { func (x *SignReceiveAuthMessageCompactRequest) Reset() { *x = SignReceiveAuthMessageCompactRequest{} - mi := &file_daemon_proto_msgTypes[26] + mi := &file_daemon_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2947,7 +3022,7 @@ func (x *SignReceiveAuthMessageCompactRequest) String() string { func (*SignReceiveAuthMessageCompactRequest) ProtoMessage() {} func (x *SignReceiveAuthMessageCompactRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[26] + mi := &file_daemon_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2960,7 +3035,7 @@ func (x *SignReceiveAuthMessageCompactRequest) ProtoReflect() protoreflect.Messa // Deprecated: Use SignReceiveAuthMessageCompactRequest.ProtoReflect.Descriptor instead. func (*SignReceiveAuthMessageCompactRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{26} + return file_daemon_proto_rawDescGZIP(), []int{27} } func (x *SignReceiveAuthMessageCompactRequest) GetPaymentHash() []byte { @@ -2994,7 +3069,7 @@ type SignReceiveAuthMessageCompactResponse struct { func (x *SignReceiveAuthMessageCompactResponse) Reset() { *x = SignReceiveAuthMessageCompactResponse{} - mi := &file_daemon_proto_msgTypes[27] + mi := &file_daemon_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3006,7 +3081,7 @@ func (x *SignReceiveAuthMessageCompactResponse) String() string { func (*SignReceiveAuthMessageCompactResponse) ProtoMessage() {} func (x *SignReceiveAuthMessageCompactResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[27] + mi := &file_daemon_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3019,7 +3094,7 @@ func (x *SignReceiveAuthMessageCompactResponse) ProtoReflect() protoreflect.Mess // Deprecated: Use SignReceiveAuthMessageCompactResponse.ProtoReflect.Descriptor instead. func (*SignReceiveAuthMessageCompactResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{27} + return file_daemon_proto_rawDescGZIP(), []int{28} } func (x *SignReceiveAuthMessageCompactResponse) GetSignature() []byte { @@ -3042,7 +3117,7 @@ type ReceiveAuthECDHRequest struct { func (x *ReceiveAuthECDHRequest) Reset() { *x = ReceiveAuthECDHRequest{} - mi := &file_daemon_proto_msgTypes[28] + mi := &file_daemon_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3054,7 +3129,7 @@ func (x *ReceiveAuthECDHRequest) String() string { func (*ReceiveAuthECDHRequest) ProtoMessage() {} func (x *ReceiveAuthECDHRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[28] + mi := &file_daemon_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3067,7 +3142,7 @@ func (x *ReceiveAuthECDHRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiveAuthECDHRequest.ProtoReflect.Descriptor instead. func (*ReceiveAuthECDHRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{28} + return file_daemon_proto_rawDescGZIP(), []int{29} } func (x *ReceiveAuthECDHRequest) GetPaymentHash() []byte { @@ -3094,7 +3169,7 @@ type ReceiveAuthECDHResponse struct { func (x *ReceiveAuthECDHResponse) Reset() { *x = ReceiveAuthECDHResponse{} - mi := &file_daemon_proto_msgTypes[29] + mi := &file_daemon_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3106,7 +3181,7 @@ func (x *ReceiveAuthECDHResponse) String() string { func (*ReceiveAuthECDHResponse) ProtoMessage() {} func (x *ReceiveAuthECDHResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[29] + mi := &file_daemon_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3119,7 +3194,7 @@ func (x *ReceiveAuthECDHResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiveAuthECDHResponse.ProtoReflect.Descriptor instead. func (*ReceiveAuthECDHResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{29} + return file_daemon_proto_rawDescGZIP(), []int{30} } func (x *ReceiveAuthECDHResponse) GetSharedSecret() []byte { @@ -3142,7 +3217,7 @@ type GetIndexedVTXOByPkScriptRequest struct { func (x *GetIndexedVTXOByPkScriptRequest) Reset() { *x = GetIndexedVTXOByPkScriptRequest{} - mi := &file_daemon_proto_msgTypes[30] + mi := &file_daemon_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3154,7 +3229,7 @@ func (x *GetIndexedVTXOByPkScriptRequest) String() string { func (*GetIndexedVTXOByPkScriptRequest) ProtoMessage() {} func (x *GetIndexedVTXOByPkScriptRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[30] + mi := &file_daemon_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3167,7 +3242,7 @@ func (x *GetIndexedVTXOByPkScriptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetIndexedVTXOByPkScriptRequest.ProtoReflect.Descriptor instead. func (*GetIndexedVTXOByPkScriptRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{30} + return file_daemon_proto_rawDescGZIP(), []int{31} } func (x *GetIndexedVTXOByPkScriptRequest) GetPkScript() []byte { @@ -3194,7 +3269,7 @@ type GetIndexedVTXOByPkScriptResponse struct { func (x *GetIndexedVTXOByPkScriptResponse) Reset() { *x = GetIndexedVTXOByPkScriptResponse{} - mi := &file_daemon_proto_msgTypes[31] + mi := &file_daemon_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3206,7 +3281,7 @@ func (x *GetIndexedVTXOByPkScriptResponse) String() string { func (*GetIndexedVTXOByPkScriptResponse) ProtoMessage() {} func (x *GetIndexedVTXOByPkScriptResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[31] + mi := &file_daemon_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3219,7 +3294,7 @@ func (x *GetIndexedVTXOByPkScriptResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetIndexedVTXOByPkScriptResponse.ProtoReflect.Descriptor instead. func (*GetIndexedVTXOByPkScriptResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{31} + return file_daemon_proto_rawDescGZIP(), []int{32} } func (x *GetIndexedVTXOByPkScriptResponse) GetVtxo() *VTXO { @@ -3255,7 +3330,7 @@ type GetVTXOExpiryInfoRequest struct { func (x *GetVTXOExpiryInfoRequest) Reset() { *x = GetVTXOExpiryInfoRequest{} - mi := &file_daemon_proto_msgTypes[32] + mi := &file_daemon_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3267,7 +3342,7 @@ func (x *GetVTXOExpiryInfoRequest) String() string { func (*GetVTXOExpiryInfoRequest) ProtoMessage() {} func (x *GetVTXOExpiryInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[32] + mi := &file_daemon_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3280,7 +3355,7 @@ func (x *GetVTXOExpiryInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVTXOExpiryInfoRequest.ProtoReflect.Descriptor instead. func (*GetVTXOExpiryInfoRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{32} + return file_daemon_proto_rawDescGZIP(), []int{33} } func (x *GetVTXOExpiryInfoRequest) GetTarget() isGetVTXOExpiryInfoRequest_Target { @@ -3357,7 +3432,7 @@ type GetVTXOExpiryInfoResponse struct { func (x *GetVTXOExpiryInfoResponse) Reset() { *x = GetVTXOExpiryInfoResponse{} - mi := &file_daemon_proto_msgTypes[33] + mi := &file_daemon_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3369,7 +3444,7 @@ func (x *GetVTXOExpiryInfoResponse) String() string { func (*GetVTXOExpiryInfoResponse) ProtoMessage() {} func (x *GetVTXOExpiryInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[33] + mi := &file_daemon_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3382,7 +3457,7 @@ func (x *GetVTXOExpiryInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVTXOExpiryInfoResponse.ProtoReflect.Descriptor instead. func (*GetVTXOExpiryInfoResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{33} + return file_daemon_proto_rawDescGZIP(), []int{34} } func (x *GetVTXOExpiryInfoResponse) GetFound() bool { @@ -3418,7 +3493,7 @@ type GetIndexedOORSessionByTxidRequest struct { func (x *GetIndexedOORSessionByTxidRequest) Reset() { *x = GetIndexedOORSessionByTxidRequest{} - mi := &file_daemon_proto_msgTypes[34] + mi := &file_daemon_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3430,7 +3505,7 @@ func (x *GetIndexedOORSessionByTxidRequest) String() string { func (*GetIndexedOORSessionByTxidRequest) ProtoMessage() {} func (x *GetIndexedOORSessionByTxidRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[34] + mi := &file_daemon_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3443,7 +3518,7 @@ func (x *GetIndexedOORSessionByTxidRequest) ProtoReflect() protoreflect.Message // Deprecated: Use GetIndexedOORSessionByTxidRequest.ProtoReflect.Descriptor instead. func (*GetIndexedOORSessionByTxidRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{34} + return file_daemon_proto_rawDescGZIP(), []int{35} } func (x *GetIndexedOORSessionByTxidRequest) GetPkScript() []byte { @@ -3473,7 +3548,7 @@ type GetIndexedOORSessionByTxidResponse struct { func (x *GetIndexedOORSessionByTxidResponse) Reset() { *x = GetIndexedOORSessionByTxidResponse{} - mi := &file_daemon_proto_msgTypes[35] + mi := &file_daemon_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3485,7 +3560,7 @@ func (x *GetIndexedOORSessionByTxidResponse) String() string { func (*GetIndexedOORSessionByTxidResponse) ProtoMessage() {} func (x *GetIndexedOORSessionByTxidResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[35] + mi := &file_daemon_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3498,7 +3573,7 @@ func (x *GetIndexedOORSessionByTxidResponse) ProtoReflect() protoreflect.Message // Deprecated: Use GetIndexedOORSessionByTxidResponse.ProtoReflect.Descriptor instead. func (*GetIndexedOORSessionByTxidResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{35} + return file_daemon_proto_rawDescGZIP(), []int{36} } func (x *GetIndexedOORSessionByTxidResponse) GetArkPsbt() []byte { @@ -3536,7 +3611,7 @@ type Output struct { func (x *Output) Reset() { *x = Output{} - mi := &file_daemon_proto_msgTypes[36] + mi := &file_daemon_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3548,7 +3623,7 @@ func (x *Output) String() string { func (*Output) ProtoMessage() {} func (x *Output) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[36] + mi := &file_daemon_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3561,7 +3636,7 @@ func (x *Output) ProtoReflect() protoreflect.Message { // Deprecated: Use Output.ProtoReflect.Descriptor instead. func (*Output) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{36} + return file_daemon_proto_rawDescGZIP(), []int{37} } func (x *Output) GetDestination() isOutput_Destination { @@ -3658,7 +3733,7 @@ type SendVTXORequest struct { func (x *SendVTXORequest) Reset() { *x = SendVTXORequest{} - mi := &file_daemon_proto_msgTypes[37] + mi := &file_daemon_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3670,7 +3745,7 @@ func (x *SendVTXORequest) String() string { func (*SendVTXORequest) ProtoMessage() {} func (x *SendVTXORequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[37] + mi := &file_daemon_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3683,7 +3758,7 @@ func (x *SendVTXORequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SendVTXORequest.ProtoReflect.Descriptor instead. func (*SendVTXORequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{37} + return file_daemon_proto_rawDescGZIP(), []int{38} } func (x *SendVTXORequest) GetRecipients() []*Output { @@ -3723,7 +3798,7 @@ type SendVTXOResponse struct { func (x *SendVTXOResponse) Reset() { *x = SendVTXOResponse{} - mi := &file_daemon_proto_msgTypes[38] + mi := &file_daemon_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3735,7 +3810,7 @@ func (x *SendVTXOResponse) String() string { func (*SendVTXOResponse) ProtoMessage() {} func (x *SendVTXOResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[38] + mi := &file_daemon_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3748,7 +3823,7 @@ func (x *SendVTXOResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SendVTXOResponse.ProtoReflect.Descriptor instead. func (*SendVTXOResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{38} + return file_daemon_proto_rawDescGZIP(), []int{39} } func (x *SendVTXOResponse) GetStatus() string { @@ -3815,7 +3890,7 @@ type SendOORRequest struct { func (x *SendOORRequest) Reset() { *x = SendOORRequest{} - mi := &file_daemon_proto_msgTypes[39] + mi := &file_daemon_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3827,7 +3902,7 @@ func (x *SendOORRequest) String() string { func (*SendOORRequest) ProtoMessage() {} func (x *SendOORRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[39] + mi := &file_daemon_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3840,7 +3915,7 @@ func (x *SendOORRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SendOORRequest.ProtoReflect.Descriptor instead. func (*SendOORRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{39} + return file_daemon_proto_rawDescGZIP(), []int{40} } func (x *SendOORRequest) GetRecipients() []*Output { @@ -3915,7 +3990,7 @@ type TaprootAssetOORIntent struct { func (x *TaprootAssetOORIntent) Reset() { *x = TaprootAssetOORIntent{} - mi := &file_daemon_proto_msgTypes[40] + mi := &file_daemon_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3927,7 +4002,7 @@ func (x *TaprootAssetOORIntent) String() string { func (*TaprootAssetOORIntent) ProtoMessage() {} func (x *TaprootAssetOORIntent) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[40] + mi := &file_daemon_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3940,7 +4015,7 @@ func (x *TaprootAssetOORIntent) ProtoReflect() protoreflect.Message { // Deprecated: Use TaprootAssetOORIntent.ProtoReflect.Descriptor instead. func (*TaprootAssetOORIntent) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{40} + return file_daemon_proto_rawDescGZIP(), []int{41} } func (x *TaprootAssetOORIntent) GetAssetRef() string { @@ -4027,7 +4102,7 @@ type CustomOORInput struct { func (x *CustomOORInput) Reset() { *x = CustomOORInput{} - mi := &file_daemon_proto_msgTypes[41] + mi := &file_daemon_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4039,7 +4114,7 @@ func (x *CustomOORInput) String() string { func (*CustomOORInput) ProtoMessage() {} func (x *CustomOORInput) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[41] + mi := &file_daemon_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4052,7 +4127,7 @@ func (x *CustomOORInput) ProtoReflect() protoreflect.Message { // Deprecated: Use CustomOORInput.ProtoReflect.Descriptor instead. func (*CustomOORInput) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{41} + return file_daemon_proto_rawDescGZIP(), []int{42} } func (x *CustomOORInput) GetOutpoint() string { @@ -4117,7 +4192,7 @@ type TaprootScriptSignature struct { func (x *TaprootScriptSignature) Reset() { *x = TaprootScriptSignature{} - mi := &file_daemon_proto_msgTypes[42] + mi := &file_daemon_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4129,7 +4204,7 @@ func (x *TaprootScriptSignature) String() string { func (*TaprootScriptSignature) ProtoMessage() {} func (x *TaprootScriptSignature) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[42] + mi := &file_daemon_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4142,7 +4217,7 @@ func (x *TaprootScriptSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use TaprootScriptSignature.ProtoReflect.Descriptor instead. func (*TaprootScriptSignature) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{42} + return file_daemon_proto_rawDescGZIP(), []int{43} } func (x *TaprootScriptSignature) GetPubkey() []byte { @@ -4193,7 +4268,7 @@ type SendOORResponse struct { func (x *SendOORResponse) Reset() { *x = SendOORResponse{} - mi := &file_daemon_proto_msgTypes[43] + mi := &file_daemon_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4205,7 +4280,7 @@ func (x *SendOORResponse) String() string { func (*SendOORResponse) ProtoMessage() {} func (x *SendOORResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[43] + mi := &file_daemon_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4218,7 +4293,7 @@ func (x *SendOORResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SendOORResponse.ProtoReflect.Descriptor instead. func (*SendOORResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{43} + return file_daemon_proto_rawDescGZIP(), []int{44} } func (x *SendOORResponse) GetStatus() string { @@ -4256,7 +4331,7 @@ type PrepareOORRequest struct { func (x *PrepareOORRequest) Reset() { *x = PrepareOORRequest{} - mi := &file_daemon_proto_msgTypes[44] + mi := &file_daemon_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4268,7 +4343,7 @@ func (x *PrepareOORRequest) String() string { func (*PrepareOORRequest) ProtoMessage() {} func (x *PrepareOORRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[44] + mi := &file_daemon_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4281,7 +4356,7 @@ func (x *PrepareOORRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareOORRequest.ProtoReflect.Descriptor instead. func (*PrepareOORRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{44} + return file_daemon_proto_rawDescGZIP(), []int{45} } func (x *PrepareOORRequest) GetRecipient() *Output { @@ -4316,7 +4391,7 @@ type PreparedOORCustomInput struct { func (x *PreparedOORCustomInput) Reset() { *x = PreparedOORCustomInput{} - mi := &file_daemon_proto_msgTypes[45] + mi := &file_daemon_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4328,7 +4403,7 @@ func (x *PreparedOORCustomInput) String() string { func (*PreparedOORCustomInput) ProtoMessage() {} func (x *PreparedOORCustomInput) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[45] + mi := &file_daemon_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4341,7 +4416,7 @@ func (x *PreparedOORCustomInput) ProtoReflect() protoreflect.Message { // Deprecated: Use PreparedOORCustomInput.ProtoReflect.Descriptor instead. func (*PreparedOORCustomInput) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{45} + return file_daemon_proto_rawDescGZIP(), []int{46} } func (x *PreparedOORCustomInput) GetOutpoint() string { @@ -4389,7 +4464,7 @@ type PrepareOORResponse struct { func (x *PrepareOORResponse) Reset() { *x = PrepareOORResponse{} - mi := &file_daemon_proto_msgTypes[46] + mi := &file_daemon_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4401,7 +4476,7 @@ func (x *PrepareOORResponse) String() string { func (*PrepareOORResponse) ProtoMessage() {} func (x *PrepareOORResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[46] + mi := &file_daemon_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4414,7 +4489,7 @@ func (x *PrepareOORResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PrepareOORResponse.ProtoReflect.Descriptor instead. func (*PrepareOORResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{46} + return file_daemon_proto_rawDescGZIP(), []int{47} } func (x *PrepareOORResponse) GetArkPsbt() []byte { @@ -4457,7 +4532,7 @@ type SignOORCustomInputRequest struct { func (x *SignOORCustomInputRequest) Reset() { *x = SignOORCustomInputRequest{} - mi := &file_daemon_proto_msgTypes[47] + mi := &file_daemon_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4469,7 +4544,7 @@ func (x *SignOORCustomInputRequest) String() string { func (*SignOORCustomInputRequest) ProtoMessage() {} func (x *SignOORCustomInputRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[47] + mi := &file_daemon_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4482,7 +4557,7 @@ func (x *SignOORCustomInputRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignOORCustomInputRequest.ProtoReflect.Descriptor instead. func (*SignOORCustomInputRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{47} + return file_daemon_proto_rawDescGZIP(), []int{48} } func (x *SignOORCustomInputRequest) GetCustomInput() *CustomOORInput { @@ -4509,7 +4584,7 @@ type SignOORCustomInputResponse struct { func (x *SignOORCustomInputResponse) Reset() { *x = SignOORCustomInputResponse{} - mi := &file_daemon_proto_msgTypes[48] + mi := &file_daemon_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4521,7 +4596,7 @@ func (x *SignOORCustomInputResponse) String() string { func (*SignOORCustomInputResponse) ProtoMessage() {} func (x *SignOORCustomInputResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[48] + mi := &file_daemon_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4534,7 +4609,7 @@ func (x *SignOORCustomInputResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignOORCustomInputResponse.ProtoReflect.Descriptor instead. func (*SignOORCustomInputResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{48} + return file_daemon_proto_rawDescGZIP(), []int{49} } func (x *SignOORCustomInputResponse) GetSignature() *TaprootScriptSignature { @@ -4575,7 +4650,7 @@ type SignVTXOForfeitRequest struct { func (x *SignVTXOForfeitRequest) Reset() { *x = SignVTXOForfeitRequest{} - mi := &file_daemon_proto_msgTypes[49] + mi := &file_daemon_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4587,7 +4662,7 @@ func (x *SignVTXOForfeitRequest) String() string { func (*SignVTXOForfeitRequest) ProtoMessage() {} func (x *SignVTXOForfeitRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[49] + mi := &file_daemon_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4600,7 +4675,7 @@ func (x *SignVTXOForfeitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SignVTXOForfeitRequest.ProtoReflect.Descriptor instead. func (*SignVTXOForfeitRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{49} + return file_daemon_proto_rawDescGZIP(), []int{50} } func (x *SignVTXOForfeitRequest) GetVtxoOutpoint() string { @@ -4685,7 +4760,7 @@ type SignVTXOForfeitResponse struct { func (x *SignVTXOForfeitResponse) Reset() { *x = SignVTXOForfeitResponse{} - mi := &file_daemon_proto_msgTypes[50] + mi := &file_daemon_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4697,7 +4772,7 @@ func (x *SignVTXOForfeitResponse) String() string { func (*SignVTXOForfeitResponse) ProtoMessage() {} func (x *SignVTXOForfeitResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[50] + mi := &file_daemon_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4710,7 +4785,7 @@ func (x *SignVTXOForfeitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SignVTXOForfeitResponse.ProtoReflect.Descriptor instead. func (*SignVTXOForfeitResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{50} + return file_daemon_proto_rawDescGZIP(), []int{51} } func (x *SignVTXOForfeitResponse) GetPubkey() []byte { @@ -4748,7 +4823,7 @@ type ForfeitSigningContext struct { func (x *ForfeitSigningContext) Reset() { *x = ForfeitSigningContext{} - mi := &file_daemon_proto_msgTypes[51] + mi := &file_daemon_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4760,7 +4835,7 @@ func (x *ForfeitSigningContext) String() string { func (*ForfeitSigningContext) ProtoMessage() {} func (x *ForfeitSigningContext) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[51] + mi := &file_daemon_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4773,7 +4848,7 @@ func (x *ForfeitSigningContext) ProtoReflect() protoreflect.Message { // Deprecated: Use ForfeitSigningContext.ProtoReflect.Descriptor instead. func (*ForfeitSigningContext) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{51} + return file_daemon_proto_rawDescGZIP(), []int{52} } func (x *ForfeitSigningContext) GetPaymentHash() []byte { @@ -4803,7 +4878,7 @@ type OutpointSelection struct { func (x *OutpointSelection) Reset() { *x = OutpointSelection{} - mi := &file_daemon_proto_msgTypes[52] + mi := &file_daemon_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4815,7 +4890,7 @@ func (x *OutpointSelection) String() string { func (*OutpointSelection) ProtoMessage() {} func (x *OutpointSelection) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[52] + mi := &file_daemon_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4828,7 +4903,7 @@ func (x *OutpointSelection) ProtoReflect() protoreflect.Message { // Deprecated: Use OutpointSelection.ProtoReflect.Descriptor instead. func (*OutpointSelection) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{52} + return file_daemon_proto_rawDescGZIP(), []int{53} } func (x *OutpointSelection) GetOutpoints() []string { @@ -4853,7 +4928,7 @@ type RefreshVTXOsRequest struct { func (x *RefreshVTXOsRequest) Reset() { *x = RefreshVTXOsRequest{} - mi := &file_daemon_proto_msgTypes[53] + mi := &file_daemon_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4865,7 +4940,7 @@ func (x *RefreshVTXOsRequest) String() string { func (*RefreshVTXOsRequest) ProtoMessage() {} func (x *RefreshVTXOsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[53] + mi := &file_daemon_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4878,7 +4953,7 @@ func (x *RefreshVTXOsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshVTXOsRequest.ProtoReflect.Descriptor instead. func (*RefreshVTXOsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{53} + return file_daemon_proto_rawDescGZIP(), []int{54} } func (x *RefreshVTXOsRequest) GetSelection() isRefreshVTXOsRequest_Selection { @@ -4950,7 +5025,7 @@ type RefreshVTXOsResponse struct { func (x *RefreshVTXOsResponse) Reset() { *x = RefreshVTXOsResponse{} - mi := &file_daemon_proto_msgTypes[54] + mi := &file_daemon_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4962,7 +5037,7 @@ func (x *RefreshVTXOsResponse) String() string { func (*RefreshVTXOsResponse) ProtoMessage() {} func (x *RefreshVTXOsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[54] + mi := &file_daemon_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4975,7 +5050,7 @@ func (x *RefreshVTXOsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshVTXOsResponse.ProtoReflect.Descriptor instead. func (*RefreshVTXOsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{54} + return file_daemon_proto_rawDescGZIP(), []int{55} } func (x *RefreshVTXOsResponse) GetQueuedOutpoints() []string { @@ -5041,7 +5116,7 @@ type RefreshFeeEstimate struct { func (x *RefreshFeeEstimate) Reset() { *x = RefreshFeeEstimate{} - mi := &file_daemon_proto_msgTypes[55] + mi := &file_daemon_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5053,7 +5128,7 @@ func (x *RefreshFeeEstimate) String() string { func (*RefreshFeeEstimate) ProtoMessage() {} func (x *RefreshFeeEstimate) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[55] + mi := &file_daemon_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5066,7 +5141,7 @@ func (x *RefreshFeeEstimate) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshFeeEstimate.ProtoReflect.Descriptor instead. func (*RefreshFeeEstimate) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{55} + return file_daemon_proto_rawDescGZIP(), []int{56} } func (x *RefreshFeeEstimate) GetEstimatedTotalFeeSat() int64 { @@ -5134,7 +5209,7 @@ type OutpointFeeEstimate struct { func (x *OutpointFeeEstimate) Reset() { *x = OutpointFeeEstimate{} - mi := &file_daemon_proto_msgTypes[56] + mi := &file_daemon_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5146,7 +5221,7 @@ func (x *OutpointFeeEstimate) String() string { func (*OutpointFeeEstimate) ProtoMessage() {} func (x *OutpointFeeEstimate) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[56] + mi := &file_daemon_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5159,7 +5234,7 @@ func (x *OutpointFeeEstimate) ProtoReflect() protoreflect.Message { // Deprecated: Use OutpointFeeEstimate.ProtoReflect.Descriptor instead. func (*OutpointFeeEstimate) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{56} + return file_daemon_proto_rawDescGZIP(), []int{57} } func (x *OutpointFeeEstimate) GetOutpoint() string { @@ -5259,7 +5334,7 @@ type CustomRefreshVTXOInput struct { func (x *CustomRefreshVTXOInput) Reset() { *x = CustomRefreshVTXOInput{} - mi := &file_daemon_proto_msgTypes[57] + mi := &file_daemon_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5271,7 +5346,7 @@ func (x *CustomRefreshVTXOInput) String() string { func (*CustomRefreshVTXOInput) ProtoMessage() {} func (x *CustomRefreshVTXOInput) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[57] + mi := &file_daemon_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5284,7 +5359,7 @@ func (x *CustomRefreshVTXOInput) ProtoReflect() protoreflect.Message { // Deprecated: Use CustomRefreshVTXOInput.ProtoReflect.Descriptor instead. func (*CustomRefreshVTXOInput) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{57} + return file_daemon_proto_rawDescGZIP(), []int{58} } func (x *CustomRefreshVTXOInput) GetOutpoint() string { @@ -5358,7 +5433,7 @@ type CustomRefreshVTXOOutput struct { func (x *CustomRefreshVTXOOutput) Reset() { *x = CustomRefreshVTXOOutput{} - mi := &file_daemon_proto_msgTypes[58] + mi := &file_daemon_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5370,7 +5445,7 @@ func (x *CustomRefreshVTXOOutput) String() string { func (*CustomRefreshVTXOOutput) ProtoMessage() {} func (x *CustomRefreshVTXOOutput) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[58] + mi := &file_daemon_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5383,7 +5458,7 @@ func (x *CustomRefreshVTXOOutput) ProtoReflect() protoreflect.Message { // Deprecated: Use CustomRefreshVTXOOutput.ProtoReflect.Descriptor instead. func (*CustomRefreshVTXOOutput) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{58} + return file_daemon_proto_rawDescGZIP(), []int{59} } func (x *CustomRefreshVTXOOutput) GetAmountSat() int64 { @@ -5430,7 +5505,7 @@ type RefreshCustomVTXOsRequest struct { func (x *RefreshCustomVTXOsRequest) Reset() { *x = RefreshCustomVTXOsRequest{} - mi := &file_daemon_proto_msgTypes[59] + mi := &file_daemon_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5442,7 +5517,7 @@ func (x *RefreshCustomVTXOsRequest) String() string { func (*RefreshCustomVTXOsRequest) ProtoMessage() {} func (x *RefreshCustomVTXOsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[59] + mi := &file_daemon_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5455,7 +5530,7 @@ func (x *RefreshCustomVTXOsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshCustomVTXOsRequest.ProtoReflect.Descriptor instead. func (*RefreshCustomVTXOsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{59} + return file_daemon_proto_rawDescGZIP(), []int{60} } func (x *RefreshCustomVTXOsRequest) GetInputs() []*CustomRefreshVTXOInput { @@ -5491,7 +5566,7 @@ type RefreshCustomVTXOsResponse struct { func (x *RefreshCustomVTXOsResponse) Reset() { *x = RefreshCustomVTXOsResponse{} - mi := &file_daemon_proto_msgTypes[60] + mi := &file_daemon_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5503,7 +5578,7 @@ func (x *RefreshCustomVTXOsResponse) String() string { func (*RefreshCustomVTXOsResponse) ProtoMessage() {} func (x *RefreshCustomVTXOsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[60] + mi := &file_daemon_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5516,7 +5591,7 @@ func (x *RefreshCustomVTXOsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RefreshCustomVTXOsResponse.ProtoReflect.Descriptor instead. func (*RefreshCustomVTXOsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{60} + return file_daemon_proto_rawDescGZIP(), []int{61} } func (x *RefreshCustomVTXOsResponse) GetQueuedOutpoints() []string { @@ -5585,7 +5660,7 @@ type PendingForfeitParticipantSignatureRequest struct { func (x *PendingForfeitParticipantSignatureRequest) Reset() { *x = PendingForfeitParticipantSignatureRequest{} - mi := &file_daemon_proto_msgTypes[61] + mi := &file_daemon_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5597,7 +5672,7 @@ func (x *PendingForfeitParticipantSignatureRequest) String() string { func (*PendingForfeitParticipantSignatureRequest) ProtoMessage() {} func (x *PendingForfeitParticipantSignatureRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[61] + mi := &file_daemon_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5610,7 +5685,7 @@ func (x *PendingForfeitParticipantSignatureRequest) ProtoReflect() protoreflect. // Deprecated: Use PendingForfeitParticipantSignatureRequest.ProtoReflect.Descriptor instead. func (*PendingForfeitParticipantSignatureRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{61} + return file_daemon_proto_rawDescGZIP(), []int{62} } func (x *PendingForfeitParticipantSignatureRequest) GetRequestId() []byte { @@ -5724,7 +5799,7 @@ type ListPendingForfeitParticipantSignatureRequestsRequest struct { func (x *ListPendingForfeitParticipantSignatureRequestsRequest) Reset() { *x = ListPendingForfeitParticipantSignatureRequestsRequest{} - mi := &file_daemon_proto_msgTypes[62] + mi := &file_daemon_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5736,7 +5811,7 @@ func (x *ListPendingForfeitParticipantSignatureRequestsRequest) String() string func (*ListPendingForfeitParticipantSignatureRequestsRequest) ProtoMessage() {} func (x *ListPendingForfeitParticipantSignatureRequestsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[62] + mi := &file_daemon_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5749,7 +5824,7 @@ func (x *ListPendingForfeitParticipantSignatureRequestsRequest) ProtoReflect() p // Deprecated: Use ListPendingForfeitParticipantSignatureRequestsRequest.ProtoReflect.Descriptor instead. func (*ListPendingForfeitParticipantSignatureRequestsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{62} + return file_daemon_proto_rawDescGZIP(), []int{63} } func (x *ListPendingForfeitParticipantSignatureRequestsRequest) GetAfterSequence() uint64 { @@ -5776,7 +5851,7 @@ type ListPendingForfeitParticipantSignatureRequestsResponse struct { func (x *ListPendingForfeitParticipantSignatureRequestsResponse) Reset() { *x = ListPendingForfeitParticipantSignatureRequestsResponse{} - mi := &file_daemon_proto_msgTypes[63] + mi := &file_daemon_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5788,7 +5863,7 @@ func (x *ListPendingForfeitParticipantSignatureRequestsResponse) String() string func (*ListPendingForfeitParticipantSignatureRequestsResponse) ProtoMessage() {} func (x *ListPendingForfeitParticipantSignatureRequestsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[63] + mi := &file_daemon_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5801,7 +5876,7 @@ func (x *ListPendingForfeitParticipantSignatureRequestsResponse) ProtoReflect() // Deprecated: Use ListPendingForfeitParticipantSignatureRequestsResponse.ProtoReflect.Descriptor instead. func (*ListPendingForfeitParticipantSignatureRequestsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{63} + return file_daemon_proto_rawDescGZIP(), []int{64} } func (x *ListPendingForfeitParticipantSignatureRequestsResponse) GetRequests() []*PendingForfeitParticipantSignatureRequest { @@ -5833,7 +5908,7 @@ type ForfeitParticipantSignature struct { func (x *ForfeitParticipantSignature) Reset() { *x = ForfeitParticipantSignature{} - mi := &file_daemon_proto_msgTypes[64] + mi := &file_daemon_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5845,7 +5920,7 @@ func (x *ForfeitParticipantSignature) String() string { func (*ForfeitParticipantSignature) ProtoMessage() {} func (x *ForfeitParticipantSignature) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[64] + mi := &file_daemon_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5858,7 +5933,7 @@ func (x *ForfeitParticipantSignature) ProtoReflect() protoreflect.Message { // Deprecated: Use ForfeitParticipantSignature.ProtoReflect.Descriptor instead. func (*ForfeitParticipantSignature) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{64} + return file_daemon_proto_rawDescGZIP(), []int{65} } func (x *ForfeitParticipantSignature) GetPubkey() []byte { @@ -5892,7 +5967,7 @@ type SubmitForfeitParticipantSignaturesRequest struct { func (x *SubmitForfeitParticipantSignaturesRequest) Reset() { *x = SubmitForfeitParticipantSignaturesRequest{} - mi := &file_daemon_proto_msgTypes[65] + mi := &file_daemon_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5904,7 +5979,7 @@ func (x *SubmitForfeitParticipantSignaturesRequest) String() string { func (*SubmitForfeitParticipantSignaturesRequest) ProtoMessage() {} func (x *SubmitForfeitParticipantSignaturesRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[65] + mi := &file_daemon_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5917,7 +5992,7 @@ func (x *SubmitForfeitParticipantSignaturesRequest) ProtoReflect() protoreflect. // Deprecated: Use SubmitForfeitParticipantSignaturesRequest.ProtoReflect.Descriptor instead. func (*SubmitForfeitParticipantSignaturesRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{65} + return file_daemon_proto_rawDescGZIP(), []int{66} } func (x *SubmitForfeitParticipantSignaturesRequest) GetRequestId() []byte { @@ -5942,7 +6017,7 @@ type SubmitForfeitParticipantSignaturesResponse struct { func (x *SubmitForfeitParticipantSignaturesResponse) Reset() { *x = SubmitForfeitParticipantSignaturesResponse{} - mi := &file_daemon_proto_msgTypes[66] + mi := &file_daemon_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5954,7 +6029,7 @@ func (x *SubmitForfeitParticipantSignaturesResponse) String() string { func (*SubmitForfeitParticipantSignaturesResponse) ProtoMessage() {} func (x *SubmitForfeitParticipantSignaturesResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[66] + mi := &file_daemon_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5967,7 +6042,7 @@ func (x *SubmitForfeitParticipantSignaturesResponse) ProtoReflect() protoreflect // Deprecated: Use SubmitForfeitParticipantSignaturesResponse.ProtoReflect.Descriptor instead. func (*SubmitForfeitParticipantSignaturesResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{66} + return file_daemon_proto_rawDescGZIP(), []int{67} } // LeaveDestination describes where a single leave output should land. @@ -5987,7 +6062,7 @@ type LeaveDestination struct { func (x *LeaveDestination) Reset() { *x = LeaveDestination{} - mi := &file_daemon_proto_msgTypes[67] + mi := &file_daemon_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5999,7 +6074,7 @@ func (x *LeaveDestination) String() string { func (*LeaveDestination) ProtoMessage() {} func (x *LeaveDestination) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[67] + mi := &file_daemon_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6012,7 +6087,7 @@ func (x *LeaveDestination) ProtoReflect() protoreflect.Message { // Deprecated: Use LeaveDestination.ProtoReflect.Descriptor instead. func (*LeaveDestination) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{67} + return file_daemon_proto_rawDescGZIP(), []int{68} } func (x *LeaveDestination) GetTarget() isLeaveDestination_Target { @@ -6093,7 +6168,7 @@ type LeaveVTXOsRequest struct { func (x *LeaveVTXOsRequest) Reset() { *x = LeaveVTXOsRequest{} - mi := &file_daemon_proto_msgTypes[68] + mi := &file_daemon_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6105,7 +6180,7 @@ func (x *LeaveVTXOsRequest) String() string { func (*LeaveVTXOsRequest) ProtoMessage() {} func (x *LeaveVTXOsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[68] + mi := &file_daemon_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6118,7 +6193,7 @@ func (x *LeaveVTXOsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LeaveVTXOsRequest.ProtoReflect.Descriptor instead. func (*LeaveVTXOsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{68} + return file_daemon_proto_rawDescGZIP(), []int{69} } func (x *LeaveVTXOsRequest) GetSelection() isLeaveVTXOsRequest_Selection { @@ -6201,7 +6276,7 @@ type LeaveVTXOsResponse struct { func (x *LeaveVTXOsResponse) Reset() { *x = LeaveVTXOsResponse{} - mi := &file_daemon_proto_msgTypes[69] + mi := &file_daemon_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6213,7 +6288,7 @@ func (x *LeaveVTXOsResponse) String() string { func (*LeaveVTXOsResponse) ProtoMessage() {} func (x *LeaveVTXOsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[69] + mi := &file_daemon_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6226,7 +6301,7 @@ func (x *LeaveVTXOsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LeaveVTXOsResponse.ProtoReflect.Descriptor instead. func (*LeaveVTXOsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{69} + return file_daemon_proto_rawDescGZIP(), []int{70} } func (x *LeaveVTXOsResponse) GetQueuedOutpoints() []string { @@ -6264,7 +6339,7 @@ type SendOnChainRequest struct { func (x *SendOnChainRequest) Reset() { *x = SendOnChainRequest{} - mi := &file_daemon_proto_msgTypes[70] + mi := &file_daemon_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6276,7 +6351,7 @@ func (x *SendOnChainRequest) String() string { func (*SendOnChainRequest) ProtoMessage() {} func (x *SendOnChainRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[70] + mi := &file_daemon_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6289,7 +6364,7 @@ func (x *SendOnChainRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SendOnChainRequest.ProtoReflect.Descriptor instead. func (*SendOnChainRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{70} + return file_daemon_proto_rawDescGZIP(), []int{71} } func (x *SendOnChainRequest) GetDestination() *LeaveDestination { @@ -6397,7 +6472,7 @@ type SendOnChainResponse struct { func (x *SendOnChainResponse) Reset() { *x = SendOnChainResponse{} - mi := &file_daemon_proto_msgTypes[71] + mi := &file_daemon_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6409,7 +6484,7 @@ func (x *SendOnChainResponse) String() string { func (*SendOnChainResponse) ProtoMessage() {} func (x *SendOnChainResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[71] + mi := &file_daemon_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6422,7 +6497,7 @@ func (x *SendOnChainResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SendOnChainResponse.ProtoReflect.Descriptor instead. func (*SendOnChainResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{71} + return file_daemon_proto_rawDescGZIP(), []int{72} } func (x *SendOnChainResponse) GetActualAmountSat() int64 { @@ -6488,7 +6563,7 @@ type BoardRequest struct { func (x *BoardRequest) Reset() { *x = BoardRequest{} - mi := &file_daemon_proto_msgTypes[72] + mi := &file_daemon_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6500,7 +6575,7 @@ func (x *BoardRequest) String() string { func (*BoardRequest) ProtoMessage() {} func (x *BoardRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[72] + mi := &file_daemon_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6513,7 +6588,7 @@ func (x *BoardRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BoardRequest.ProtoReflect.Descriptor instead. func (*BoardRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{72} + return file_daemon_proto_rawDescGZIP(), []int{73} } func (x *BoardRequest) GetTargetVtxoCount() uint32 { @@ -6544,7 +6619,7 @@ type BoardResponse struct { func (x *BoardResponse) Reset() { *x = BoardResponse{} - mi := &file_daemon_proto_msgTypes[73] + mi := &file_daemon_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6556,7 +6631,7 @@ func (x *BoardResponse) String() string { func (*BoardResponse) ProtoMessage() {} func (x *BoardResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[73] + mi := &file_daemon_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6569,7 +6644,7 @@ func (x *BoardResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BoardResponse.ProtoReflect.Descriptor instead. func (*BoardResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{73} + return file_daemon_proto_rawDescGZIP(), []int{74} } func (x *BoardResponse) GetStatus() string { @@ -6594,7 +6669,7 @@ type JoinNextRoundRequest struct { func (x *JoinNextRoundRequest) Reset() { *x = JoinNextRoundRequest{} - mi := &file_daemon_proto_msgTypes[74] + mi := &file_daemon_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6606,7 +6681,7 @@ func (x *JoinNextRoundRequest) String() string { func (*JoinNextRoundRequest) ProtoMessage() {} func (x *JoinNextRoundRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[74] + mi := &file_daemon_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6619,7 +6694,7 @@ func (x *JoinNextRoundRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use JoinNextRoundRequest.ProtoReflect.Descriptor instead. func (*JoinNextRoundRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{74} + return file_daemon_proto_rawDescGZIP(), []int{75} } type JoinNextRoundResponse struct { @@ -6634,7 +6709,7 @@ type JoinNextRoundResponse struct { func (x *JoinNextRoundResponse) Reset() { *x = JoinNextRoundResponse{} - mi := &file_daemon_proto_msgTypes[75] + mi := &file_daemon_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6646,7 +6721,7 @@ func (x *JoinNextRoundResponse) String() string { func (*JoinNextRoundResponse) ProtoMessage() {} func (x *JoinNextRoundResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[75] + mi := &file_daemon_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6659,7 +6734,7 @@ func (x *JoinNextRoundResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use JoinNextRoundResponse.ProtoReflect.Descriptor instead. func (*JoinNextRoundResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{75} + return file_daemon_proto_rawDescGZIP(), []int{76} } func (x *JoinNextRoundResponse) GetStatus() string { @@ -6695,7 +6770,7 @@ type SweepBoardingUTXOsRequest struct { func (x *SweepBoardingUTXOsRequest) Reset() { *x = SweepBoardingUTXOsRequest{} - mi := &file_daemon_proto_msgTypes[76] + mi := &file_daemon_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6707,7 +6782,7 @@ func (x *SweepBoardingUTXOsRequest) String() string { func (*SweepBoardingUTXOsRequest) ProtoMessage() {} func (x *SweepBoardingUTXOsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[76] + mi := &file_daemon_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6720,7 +6795,7 @@ func (x *SweepBoardingUTXOsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SweepBoardingUTXOsRequest.ProtoReflect.Descriptor instead. func (*SweepBoardingUTXOsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{76} + return file_daemon_proto_rawDescGZIP(), []int{77} } func (x *SweepBoardingUTXOsRequest) GetOutpoints() []string { @@ -6773,7 +6848,7 @@ type BoardingSweepOutput struct { func (x *BoardingSweepOutput) Reset() { *x = BoardingSweepOutput{} - mi := &file_daemon_proto_msgTypes[77] + mi := &file_daemon_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6785,7 +6860,7 @@ func (x *BoardingSweepOutput) String() string { func (*BoardingSweepOutput) ProtoMessage() {} func (x *BoardingSweepOutput) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[77] + mi := &file_daemon_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6798,7 +6873,7 @@ func (x *BoardingSweepOutput) ProtoReflect() protoreflect.Message { // Deprecated: Use BoardingSweepOutput.ProtoReflect.Descriptor instead. func (*BoardingSweepOutput) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{77} + return file_daemon_proto_rawDescGZIP(), []int{78} } func (x *BoardingSweepOutput) GetOutpoint() string { @@ -6864,7 +6939,7 @@ type SweepBoardingUTXOsResponse struct { func (x *SweepBoardingUTXOsResponse) Reset() { *x = SweepBoardingUTXOsResponse{} - mi := &file_daemon_proto_msgTypes[78] + mi := &file_daemon_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6876,7 +6951,7 @@ func (x *SweepBoardingUTXOsResponse) String() string { func (*SweepBoardingUTXOsResponse) ProtoMessage() {} func (x *SweepBoardingUTXOsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[78] + mi := &file_daemon_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6889,7 +6964,7 @@ func (x *SweepBoardingUTXOsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SweepBoardingUTXOsResponse.ProtoReflect.Descriptor instead. func (*SweepBoardingUTXOsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{78} + return file_daemon_proto_rawDescGZIP(), []int{79} } func (x *SweepBoardingUTXOsResponse) GetStatus() string { @@ -6993,7 +7068,7 @@ type ListBoardingSweepsRequest struct { func (x *ListBoardingSweepsRequest) Reset() { *x = ListBoardingSweepsRequest{} - mi := &file_daemon_proto_msgTypes[79] + mi := &file_daemon_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7005,7 +7080,7 @@ func (x *ListBoardingSweepsRequest) String() string { func (*ListBoardingSweepsRequest) ProtoMessage() {} func (x *ListBoardingSweepsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[79] + mi := &file_daemon_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7018,7 +7093,7 @@ func (x *ListBoardingSweepsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListBoardingSweepsRequest.ProtoReflect.Descriptor instead. func (*ListBoardingSweepsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{79} + return file_daemon_proto_rawDescGZIP(), []int{80} } func (x *ListBoardingSweepsRequest) GetStatus() string { @@ -7061,7 +7136,7 @@ type BoardingSweepInput struct { func (x *BoardingSweepInput) Reset() { *x = BoardingSweepInput{} - mi := &file_daemon_proto_msgTypes[80] + mi := &file_daemon_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7073,7 +7148,7 @@ func (x *BoardingSweepInput) String() string { func (*BoardingSweepInput) ProtoMessage() {} func (x *BoardingSweepInput) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[80] + mi := &file_daemon_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7086,7 +7161,7 @@ func (x *BoardingSweepInput) ProtoReflect() protoreflect.Message { // Deprecated: Use BoardingSweepInput.ProtoReflect.Descriptor instead. func (*BoardingSweepInput) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{80} + return file_daemon_proto_rawDescGZIP(), []int{81} } func (x *BoardingSweepInput) GetOutpoint() string { @@ -7156,7 +7231,7 @@ type BoardingSweep struct { func (x *BoardingSweep) Reset() { *x = BoardingSweep{} - mi := &file_daemon_proto_msgTypes[81] + mi := &file_daemon_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7168,7 +7243,7 @@ func (x *BoardingSweep) String() string { func (*BoardingSweep) ProtoMessage() {} func (x *BoardingSweep) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[81] + mi := &file_daemon_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7181,7 +7256,7 @@ func (x *BoardingSweep) ProtoReflect() protoreflect.Message { // Deprecated: Use BoardingSweep.ProtoReflect.Descriptor instead. func (*BoardingSweep) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{81} + return file_daemon_proto_rawDescGZIP(), []int{82} } func (x *BoardingSweep) GetTxid() string { @@ -7273,7 +7348,7 @@ type ListBoardingSweepsResponse struct { func (x *ListBoardingSweepsResponse) Reset() { *x = ListBoardingSweepsResponse{} - mi := &file_daemon_proto_msgTypes[82] + mi := &file_daemon_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7285,7 +7360,7 @@ func (x *ListBoardingSweepsResponse) String() string { func (*ListBoardingSweepsResponse) ProtoMessage() {} func (x *ListBoardingSweepsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[82] + mi := &file_daemon_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7298,7 +7373,7 @@ func (x *ListBoardingSweepsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListBoardingSweepsResponse.ProtoReflect.Descriptor instead. func (*ListBoardingSweepsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{82} + return file_daemon_proto_rawDescGZIP(), []int{83} } func (x *ListBoardingSweepsResponse) GetSweeps() []*BoardingSweep { @@ -7328,7 +7403,7 @@ type RoundVTXOInfo struct { func (x *RoundVTXOInfo) Reset() { *x = RoundVTXOInfo{} - mi := &file_daemon_proto_msgTypes[83] + mi := &file_daemon_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7340,7 +7415,7 @@ func (x *RoundVTXOInfo) String() string { func (*RoundVTXOInfo) ProtoMessage() {} func (x *RoundVTXOInfo) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[83] + mi := &file_daemon_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7353,7 +7428,7 @@ func (x *RoundVTXOInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundVTXOInfo.ProtoReflect.Descriptor instead. func (*RoundVTXOInfo) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{83} + return file_daemon_proto_rawDescGZIP(), []int{84} } func (x *RoundVTXOInfo) GetOutpoint() string { @@ -7421,7 +7496,7 @@ type RoundInfo struct { func (x *RoundInfo) Reset() { *x = RoundInfo{} - mi := &file_daemon_proto_msgTypes[84] + mi := &file_daemon_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7433,7 +7508,7 @@ func (x *RoundInfo) String() string { func (*RoundInfo) ProtoMessage() {} func (x *RoundInfo) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[84] + mi := &file_daemon_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7446,7 +7521,7 @@ func (x *RoundInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use RoundInfo.ProtoReflect.Descriptor instead. func (*RoundInfo) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{84} + return file_daemon_proto_rawDescGZIP(), []int{85} } func (x *RoundInfo) GetRoundId() string { @@ -7558,7 +7633,7 @@ type ListRoundsRequest struct { func (x *ListRoundsRequest) Reset() { *x = ListRoundsRequest{} - mi := &file_daemon_proto_msgTypes[85] + mi := &file_daemon_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7570,7 +7645,7 @@ func (x *ListRoundsRequest) String() string { func (*ListRoundsRequest) ProtoMessage() {} func (x *ListRoundsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[85] + mi := &file_daemon_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7583,7 +7658,7 @@ func (x *ListRoundsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRoundsRequest.ProtoReflect.Descriptor instead. func (*ListRoundsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{85} + return file_daemon_proto_rawDescGZIP(), []int{86} } func (x *ListRoundsRequest) GetPageSize() int32 { @@ -7638,7 +7713,7 @@ type GetRoundRequest struct { func (x *GetRoundRequest) Reset() { *x = GetRoundRequest{} - mi := &file_daemon_proto_msgTypes[86] + mi := &file_daemon_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7650,7 +7725,7 @@ func (x *GetRoundRequest) String() string { func (*GetRoundRequest) ProtoMessage() {} func (x *GetRoundRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[86] + mi := &file_daemon_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7663,7 +7738,7 @@ func (x *GetRoundRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoundRequest.ProtoReflect.Descriptor instead. func (*GetRoundRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{86} + return file_daemon_proto_rawDescGZIP(), []int{87} } func (x *GetRoundRequest) GetRoundId() string { @@ -7683,7 +7758,7 @@ type GetRoundResponse struct { func (x *GetRoundResponse) Reset() { *x = GetRoundResponse{} - mi := &file_daemon_proto_msgTypes[87] + mi := &file_daemon_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7695,7 +7770,7 @@ func (x *GetRoundResponse) String() string { func (*GetRoundResponse) ProtoMessage() {} func (x *GetRoundResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[87] + mi := &file_daemon_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7708,7 +7783,7 @@ func (x *GetRoundResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetRoundResponse.ProtoReflect.Descriptor instead. func (*GetRoundResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{87} + return file_daemon_proto_rawDescGZIP(), []int{88} } func (x *GetRoundResponse) GetRound() *RoundInfo { @@ -7731,7 +7806,7 @@ type ListRoundsResponse struct { func (x *ListRoundsResponse) Reset() { *x = ListRoundsResponse{} - mi := &file_daemon_proto_msgTypes[88] + mi := &file_daemon_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7743,7 +7818,7 @@ func (x *ListRoundsResponse) String() string { func (*ListRoundsResponse) ProtoMessage() {} func (x *ListRoundsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[88] + mi := &file_daemon_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7756,7 +7831,7 @@ func (x *ListRoundsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRoundsResponse.ProtoReflect.Descriptor instead. func (*ListRoundsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{88} + return file_daemon_proto_rawDescGZIP(), []int{89} } func (x *ListRoundsResponse) GetRounds() []*RoundInfo { @@ -7781,7 +7856,7 @@ type WatchRoundsRequest struct { func (x *WatchRoundsRequest) Reset() { *x = WatchRoundsRequest{} - mi := &file_daemon_proto_msgTypes[89] + mi := &file_daemon_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7793,7 +7868,7 @@ func (x *WatchRoundsRequest) String() string { func (*WatchRoundsRequest) ProtoMessage() {} func (x *WatchRoundsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[89] + mi := &file_daemon_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7806,7 +7881,7 @@ func (x *WatchRoundsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchRoundsRequest.ProtoReflect.Descriptor instead. func (*WatchRoundsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{89} + return file_daemon_proto_rawDescGZIP(), []int{90} } type WatchRoundsResponse struct { @@ -7820,7 +7895,7 @@ type WatchRoundsResponse struct { func (x *WatchRoundsResponse) Reset() { *x = WatchRoundsResponse{} - mi := &file_daemon_proto_msgTypes[90] + mi := &file_daemon_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7832,7 +7907,7 @@ func (x *WatchRoundsResponse) String() string { func (*WatchRoundsResponse) ProtoMessage() {} func (x *WatchRoundsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[90] + mi := &file_daemon_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7845,7 +7920,7 @@ func (x *WatchRoundsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchRoundsResponse.ProtoReflect.Descriptor instead. func (*WatchRoundsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{90} + return file_daemon_proto_rawDescGZIP(), []int{91} } func (x *WatchRoundsResponse) GetRound() *RoundInfo { @@ -7883,7 +7958,7 @@ type OORSessionInfo struct { func (x *OORSessionInfo) Reset() { *x = OORSessionInfo{} - mi := &file_daemon_proto_msgTypes[91] + mi := &file_daemon_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7895,7 +7970,7 @@ func (x *OORSessionInfo) String() string { func (*OORSessionInfo) ProtoMessage() {} func (x *OORSessionInfo) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[91] + mi := &file_daemon_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7908,7 +7983,7 @@ func (x *OORSessionInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use OORSessionInfo.ProtoReflect.Descriptor instead. func (*OORSessionInfo) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{91} + return file_daemon_proto_rawDescGZIP(), []int{92} } func (x *OORSessionInfo) GetSessionId() string { @@ -7992,7 +8067,7 @@ type ListOORSessionsRequest struct { func (x *ListOORSessionsRequest) Reset() { *x = ListOORSessionsRequest{} - mi := &file_daemon_proto_msgTypes[92] + mi := &file_daemon_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8004,7 +8079,7 @@ func (x *ListOORSessionsRequest) String() string { func (*ListOORSessionsRequest) ProtoMessage() {} func (x *ListOORSessionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[92] + mi := &file_daemon_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8017,7 +8092,7 @@ func (x *ListOORSessionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListOORSessionsRequest.ProtoReflect.Descriptor instead. func (*ListOORSessionsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{92} + return file_daemon_proto_rawDescGZIP(), []int{93} } func (x *ListOORSessionsRequest) GetPageSize() int32 { @@ -8061,7 +8136,7 @@ type ListOORSessionsResponse struct { func (x *ListOORSessionsResponse) Reset() { *x = ListOORSessionsResponse{} - mi := &file_daemon_proto_msgTypes[93] + mi := &file_daemon_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8073,7 +8148,7 @@ func (x *ListOORSessionsResponse) String() string { func (*ListOORSessionsResponse) ProtoMessage() {} func (x *ListOORSessionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[93] + mi := &file_daemon_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8086,7 +8161,7 @@ func (x *ListOORSessionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListOORSessionsResponse.ProtoReflect.Descriptor instead. func (*ListOORSessionsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{93} + return file_daemon_proto_rawDescGZIP(), []int{94} } func (x *ListOORSessionsResponse) GetSessions() []*OORSessionInfo { @@ -8113,7 +8188,7 @@ type GetOORSessionRequest struct { func (x *GetOORSessionRequest) Reset() { *x = GetOORSessionRequest{} - mi := &file_daemon_proto_msgTypes[94] + mi := &file_daemon_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8125,7 +8200,7 @@ func (x *GetOORSessionRequest) String() string { func (*GetOORSessionRequest) ProtoMessage() {} func (x *GetOORSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[94] + mi := &file_daemon_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8138,7 +8213,7 @@ func (x *GetOORSessionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOORSessionRequest.ProtoReflect.Descriptor instead. func (*GetOORSessionRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{94} + return file_daemon_proto_rawDescGZIP(), []int{95} } func (x *GetOORSessionRequest) GetSessionId() string { @@ -8158,7 +8233,7 @@ type GetOORSessionResponse struct { func (x *GetOORSessionResponse) Reset() { *x = GetOORSessionResponse{} - mi := &file_daemon_proto_msgTypes[95] + mi := &file_daemon_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8170,7 +8245,7 @@ func (x *GetOORSessionResponse) String() string { func (*GetOORSessionResponse) ProtoMessage() {} func (x *GetOORSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[95] + mi := &file_daemon_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8183,7 +8258,7 @@ func (x *GetOORSessionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetOORSessionResponse.ProtoReflect.Descriptor instead. func (*GetOORSessionResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{95} + return file_daemon_proto_rawDescGZIP(), []int{96} } func (x *GetOORSessionResponse) GetSession() *OORSessionInfo { @@ -8211,7 +8286,7 @@ type EstimateFeeRequest struct { func (x *EstimateFeeRequest) Reset() { *x = EstimateFeeRequest{} - mi := &file_daemon_proto_msgTypes[96] + mi := &file_daemon_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8223,7 +8298,7 @@ func (x *EstimateFeeRequest) String() string { func (*EstimateFeeRequest) ProtoMessage() {} func (x *EstimateFeeRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[96] + mi := &file_daemon_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8236,7 +8311,7 @@ func (x *EstimateFeeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EstimateFeeRequest.ProtoReflect.Descriptor instead. func (*EstimateFeeRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{96} + return file_daemon_proto_rawDescGZIP(), []int{97} } func (x *EstimateFeeRequest) GetAmountSat() int64 { @@ -8290,7 +8365,7 @@ type EstimateFeeResponse struct { func (x *EstimateFeeResponse) Reset() { *x = EstimateFeeResponse{} - mi := &file_daemon_proto_msgTypes[97] + mi := &file_daemon_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8302,7 +8377,7 @@ func (x *EstimateFeeResponse) String() string { func (*EstimateFeeResponse) ProtoMessage() {} func (x *EstimateFeeResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[97] + mi := &file_daemon_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8315,7 +8390,7 @@ func (x *EstimateFeeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EstimateFeeResponse.ProtoReflect.Descriptor instead. func (*EstimateFeeResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{97} + return file_daemon_proto_rawDescGZIP(), []int{98} } func (x *EstimateFeeResponse) GetLiquidityFeeSat() int64 { @@ -8385,7 +8460,7 @@ type GetFeeHistoryRequest struct { func (x *GetFeeHistoryRequest) Reset() { *x = GetFeeHistoryRequest{} - mi := &file_daemon_proto_msgTypes[98] + mi := &file_daemon_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8397,7 +8472,7 @@ func (x *GetFeeHistoryRequest) String() string { func (*GetFeeHistoryRequest) ProtoMessage() {} func (x *GetFeeHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[98] + mi := &file_daemon_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8410,7 +8485,7 @@ func (x *GetFeeHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFeeHistoryRequest.ProtoReflect.Descriptor instead. func (*GetFeeHistoryRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{98} + return file_daemon_proto_rawDescGZIP(), []int{99} } func (x *GetFeeHistoryRequest) GetLimit() uint32 { @@ -8485,7 +8560,7 @@ type FeeHistoryEntry struct { func (x *FeeHistoryEntry) Reset() { *x = FeeHistoryEntry{} - mi := &file_daemon_proto_msgTypes[99] + mi := &file_daemon_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8497,7 +8572,7 @@ func (x *FeeHistoryEntry) String() string { func (*FeeHistoryEntry) ProtoMessage() {} func (x *FeeHistoryEntry) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[99] + mi := &file_daemon_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8510,7 +8585,7 @@ func (x *FeeHistoryEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use FeeHistoryEntry.ProtoReflect.Descriptor instead. func (*FeeHistoryEntry) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{99} + return file_daemon_proto_rawDescGZIP(), []int{100} } func (x *FeeHistoryEntry) GetEntryId() int64 { @@ -8590,7 +8665,7 @@ type GetFeeHistoryResponse struct { func (x *GetFeeHistoryResponse) Reset() { *x = GetFeeHistoryResponse{} - mi := &file_daemon_proto_msgTypes[100] + mi := &file_daemon_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8602,7 +8677,7 @@ func (x *GetFeeHistoryResponse) String() string { func (*GetFeeHistoryResponse) ProtoMessage() {} func (x *GetFeeHistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[100] + mi := &file_daemon_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8615,7 +8690,7 @@ func (x *GetFeeHistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetFeeHistoryResponse.ProtoReflect.Descriptor instead. func (*GetFeeHistoryResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{100} + return file_daemon_proto_rawDescGZIP(), []int{101} } func (x *GetFeeHistoryResponse) GetEntries() []*FeeHistoryEntry { @@ -8656,7 +8731,7 @@ type ListTransactionsRequest struct { func (x *ListTransactionsRequest) Reset() { *x = ListTransactionsRequest{} - mi := &file_daemon_proto_msgTypes[101] + mi := &file_daemon_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8668,7 +8743,7 @@ func (x *ListTransactionsRequest) String() string { func (*ListTransactionsRequest) ProtoMessage() {} func (x *ListTransactionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[101] + mi := &file_daemon_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8681,7 +8756,7 @@ func (x *ListTransactionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTransactionsRequest.ProtoReflect.Descriptor instead. func (*ListTransactionsRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{101} + return file_daemon_proto_rawDescGZIP(), []int{102} } func (x *ListTransactionsRequest) GetFromUnixS() int64 { @@ -8772,7 +8847,7 @@ type TransactionHistoryEntry struct { func (x *TransactionHistoryEntry) Reset() { *x = TransactionHistoryEntry{} - mi := &file_daemon_proto_msgTypes[102] + mi := &file_daemon_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8784,7 +8859,7 @@ func (x *TransactionHistoryEntry) String() string { func (*TransactionHistoryEntry) ProtoMessage() {} func (x *TransactionHistoryEntry) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[102] + mi := &file_daemon_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8797,7 +8872,7 @@ func (x *TransactionHistoryEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use TransactionHistoryEntry.ProtoReflect.Descriptor instead. func (*TransactionHistoryEntry) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{102} + return file_daemon_proto_rawDescGZIP(), []int{103} } func (x *TransactionHistoryEntry) GetSource() string { @@ -8934,7 +9009,7 @@ type ListTransactionsResponse struct { func (x *ListTransactionsResponse) Reset() { *x = ListTransactionsResponse{} - mi := &file_daemon_proto_msgTypes[103] + mi := &file_daemon_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8946,7 +9021,7 @@ func (x *ListTransactionsResponse) String() string { func (*ListTransactionsResponse) ProtoMessage() {} func (x *ListTransactionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[103] + mi := &file_daemon_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8959,7 +9034,7 @@ func (x *ListTransactionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTransactionsResponse.ProtoReflect.Descriptor instead. func (*ListTransactionsResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{103} + return file_daemon_proto_rawDescGZIP(), []int{104} } func (x *ListTransactionsResponse) GetTransactions() []*TransactionHistoryEntry { @@ -8994,7 +9069,7 @@ type UnrollRequest struct { func (x *UnrollRequest) Reset() { *x = UnrollRequest{} - mi := &file_daemon_proto_msgTypes[104] + mi := &file_daemon_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9006,7 +9081,7 @@ func (x *UnrollRequest) String() string { func (*UnrollRequest) ProtoMessage() {} func (x *UnrollRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[104] + mi := &file_daemon_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9019,7 +9094,7 @@ func (x *UnrollRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UnrollRequest.ProtoReflect.Descriptor instead. func (*UnrollRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{104} + return file_daemon_proto_rawDescGZIP(), []int{105} } func (x *UnrollRequest) GetOutpoint() string { @@ -9042,7 +9117,7 @@ type UnrollResponse struct { func (x *UnrollResponse) Reset() { *x = UnrollResponse{} - mi := &file_daemon_proto_msgTypes[105] + mi := &file_daemon_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9054,7 +9129,7 @@ func (x *UnrollResponse) String() string { func (*UnrollResponse) ProtoMessage() {} func (x *UnrollResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[105] + mi := &file_daemon_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9067,7 +9142,7 @@ func (x *UnrollResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UnrollResponse.ProtoReflect.Descriptor instead. func (*UnrollResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{105} + return file_daemon_proto_rawDescGZIP(), []int{106} } func (x *UnrollResponse) GetCreated() bool { @@ -9099,7 +9174,7 @@ type GetUnrollStatusRequest struct { func (x *GetUnrollStatusRequest) Reset() { *x = GetUnrollStatusRequest{} - mi := &file_daemon_proto_msgTypes[106] + mi := &file_daemon_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9111,7 +9186,7 @@ func (x *GetUnrollStatusRequest) String() string { func (*GetUnrollStatusRequest) ProtoMessage() {} func (x *GetUnrollStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[106] + mi := &file_daemon_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9124,7 +9199,7 @@ func (x *GetUnrollStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUnrollStatusRequest.ProtoReflect.Descriptor instead. func (*GetUnrollStatusRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{106} + return file_daemon_proto_rawDescGZIP(), []int{107} } func (x *GetUnrollStatusRequest) GetOutpoint() string { @@ -9176,7 +9251,7 @@ type UnrollProgress struct { func (x *UnrollProgress) Reset() { *x = UnrollProgress{} - mi := &file_daemon_proto_msgTypes[107] + mi := &file_daemon_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9188,7 +9263,7 @@ func (x *UnrollProgress) String() string { func (*UnrollProgress) ProtoMessage() {} func (x *UnrollProgress) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[107] + mi := &file_daemon_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9201,7 +9276,7 @@ func (x *UnrollProgress) ProtoReflect() protoreflect.Message { // Deprecated: Use UnrollProgress.ProtoReflect.Descriptor instead. func (*UnrollProgress) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{107} + return file_daemon_proto_rawDescGZIP(), []int{108} } func (x *UnrollProgress) GetConfirmedTxs() uint32 { @@ -9286,7 +9361,7 @@ type UnrollCSV struct { func (x *UnrollCSV) Reset() { *x = UnrollCSV{} - mi := &file_daemon_proto_msgTypes[108] + mi := &file_daemon_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9298,7 +9373,7 @@ func (x *UnrollCSV) String() string { func (*UnrollCSV) ProtoMessage() {} func (x *UnrollCSV) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[108] + mi := &file_daemon_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9311,7 +9386,7 @@ func (x *UnrollCSV) ProtoReflect() protoreflect.Message { // Deprecated: Use UnrollCSV.ProtoReflect.Descriptor instead. func (*UnrollCSV) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{108} + return file_daemon_proto_rawDescGZIP(), []int{109} } func (x *UnrollCSV) GetTargetConfirmHeight() int32 { @@ -9376,7 +9451,7 @@ type UnrollFees struct { func (x *UnrollFees) Reset() { *x = UnrollFees{} - mi := &file_daemon_proto_msgTypes[109] + mi := &file_daemon_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9388,7 +9463,7 @@ func (x *UnrollFees) String() string { func (*UnrollFees) ProtoMessage() {} func (x *UnrollFees) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[109] + mi := &file_daemon_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9401,7 +9476,7 @@ func (x *UnrollFees) ProtoReflect() protoreflect.Message { // Deprecated: Use UnrollFees.ProtoReflect.Descriptor instead. func (*UnrollFees) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{109} + return file_daemon_proto_rawDescGZIP(), []int{110} } func (x *UnrollFees) GetCpfpFeeSat() int64 { @@ -9503,7 +9578,7 @@ type GetUnrollStatusResponse struct { func (x *GetUnrollStatusResponse) Reset() { *x = GetUnrollStatusResponse{} - mi := &file_daemon_proto_msgTypes[110] + mi := &file_daemon_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9515,7 +9590,7 @@ func (x *GetUnrollStatusResponse) String() string { func (*GetUnrollStatusResponse) ProtoMessage() {} func (x *GetUnrollStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[110] + mi := &file_daemon_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9528,7 +9603,7 @@ func (x *GetUnrollStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUnrollStatusResponse.ProtoReflect.Descriptor instead. func (*GetUnrollStatusResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{110} + return file_daemon_proto_rawDescGZIP(), []int{111} } func (x *GetUnrollStatusResponse) GetFound() bool { @@ -9659,7 +9734,7 @@ type ArmVHTLCRecoveryRequest struct { func (x *ArmVHTLCRecoveryRequest) Reset() { *x = ArmVHTLCRecoveryRequest{} - mi := &file_daemon_proto_msgTypes[111] + mi := &file_daemon_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9671,7 +9746,7 @@ func (x *ArmVHTLCRecoveryRequest) String() string { func (*ArmVHTLCRecoveryRequest) ProtoMessage() {} func (x *ArmVHTLCRecoveryRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[111] + mi := &file_daemon_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9684,7 +9759,7 @@ func (x *ArmVHTLCRecoveryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ArmVHTLCRecoveryRequest.ProtoReflect.Descriptor instead. func (*ArmVHTLCRecoveryRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{111} + return file_daemon_proto_rawDescGZIP(), []int{112} } func (x *ArmVHTLCRecoveryRequest) GetRequestId() string { @@ -9827,7 +9902,7 @@ type ArmVHTLCRecoveryResponse struct { func (x *ArmVHTLCRecoveryResponse) Reset() { *x = ArmVHTLCRecoveryResponse{} - mi := &file_daemon_proto_msgTypes[112] + mi := &file_daemon_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9839,7 +9914,7 @@ func (x *ArmVHTLCRecoveryResponse) String() string { func (*ArmVHTLCRecoveryResponse) ProtoMessage() {} func (x *ArmVHTLCRecoveryResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[112] + mi := &file_daemon_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9852,7 +9927,7 @@ func (x *ArmVHTLCRecoveryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ArmVHTLCRecoveryResponse.ProtoReflect.Descriptor instead. func (*ArmVHTLCRecoveryResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{112} + return file_daemon_proto_rawDescGZIP(), []int{113} } func (x *ArmVHTLCRecoveryResponse) GetRecoveryId() string { @@ -9892,7 +9967,7 @@ type EscalateVHTLCRecoveryRequest struct { func (x *EscalateVHTLCRecoveryRequest) Reset() { *x = EscalateVHTLCRecoveryRequest{} - mi := &file_daemon_proto_msgTypes[113] + mi := &file_daemon_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9904,7 +9979,7 @@ func (x *EscalateVHTLCRecoveryRequest) String() string { func (*EscalateVHTLCRecoveryRequest) ProtoMessage() {} func (x *EscalateVHTLCRecoveryRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[113] + mi := &file_daemon_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9917,7 +9992,7 @@ func (x *EscalateVHTLCRecoveryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EscalateVHTLCRecoveryRequest.ProtoReflect.Descriptor instead. func (*EscalateVHTLCRecoveryRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{113} + return file_daemon_proto_rawDescGZIP(), []int{114} } func (x *EscalateVHTLCRecoveryRequest) GetRecoveryId() string { @@ -9951,7 +10026,7 @@ type EscalateVHTLCRecoveryResponse struct { func (x *EscalateVHTLCRecoveryResponse) Reset() { *x = EscalateVHTLCRecoveryResponse{} - mi := &file_daemon_proto_msgTypes[114] + mi := &file_daemon_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9963,7 +10038,7 @@ func (x *EscalateVHTLCRecoveryResponse) String() string { func (*EscalateVHTLCRecoveryResponse) ProtoMessage() {} func (x *EscalateVHTLCRecoveryResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[114] + mi := &file_daemon_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9976,7 +10051,7 @@ func (x *EscalateVHTLCRecoveryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EscalateVHTLCRecoveryResponse.ProtoReflect.Descriptor instead. func (*EscalateVHTLCRecoveryResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{114} + return file_daemon_proto_rawDescGZIP(), []int{115} } func (x *EscalateVHTLCRecoveryResponse) GetStatus() *VHTLCRecoveryStatus { @@ -10000,7 +10075,7 @@ type CancelVHTLCRecoveryRequest struct { func (x *CancelVHTLCRecoveryRequest) Reset() { *x = CancelVHTLCRecoveryRequest{} - mi := &file_daemon_proto_msgTypes[115] + mi := &file_daemon_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10012,7 +10087,7 @@ func (x *CancelVHTLCRecoveryRequest) String() string { func (*CancelVHTLCRecoveryRequest) ProtoMessage() {} func (x *CancelVHTLCRecoveryRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[115] + mi := &file_daemon_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10025,7 +10100,7 @@ func (x *CancelVHTLCRecoveryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelVHTLCRecoveryRequest.ProtoReflect.Descriptor instead. func (*CancelVHTLCRecoveryRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{115} + return file_daemon_proto_rawDescGZIP(), []int{116} } func (x *CancelVHTLCRecoveryRequest) GetRecoveryId() string { @@ -10059,7 +10134,7 @@ type CancelVHTLCRecoveryResponse struct { func (x *CancelVHTLCRecoveryResponse) Reset() { *x = CancelVHTLCRecoveryResponse{} - mi := &file_daemon_proto_msgTypes[116] + mi := &file_daemon_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10071,7 +10146,7 @@ func (x *CancelVHTLCRecoveryResponse) String() string { func (*CancelVHTLCRecoveryResponse) ProtoMessage() {} func (x *CancelVHTLCRecoveryResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[116] + mi := &file_daemon_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10084,7 +10159,7 @@ func (x *CancelVHTLCRecoveryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelVHTLCRecoveryResponse.ProtoReflect.Descriptor instead. func (*CancelVHTLCRecoveryResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{116} + return file_daemon_proto_rawDescGZIP(), []int{117} } func (x *CancelVHTLCRecoveryResponse) GetStatus() *VHTLCRecoveryStatus { @@ -10104,7 +10179,7 @@ type GetVHTLCRecoveryStatusRequest struct { func (x *GetVHTLCRecoveryStatusRequest) Reset() { *x = GetVHTLCRecoveryStatusRequest{} - mi := &file_daemon_proto_msgTypes[117] + mi := &file_daemon_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10116,7 +10191,7 @@ func (x *GetVHTLCRecoveryStatusRequest) String() string { func (*GetVHTLCRecoveryStatusRequest) ProtoMessage() {} func (x *GetVHTLCRecoveryStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[117] + mi := &file_daemon_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10129,7 +10204,7 @@ func (x *GetVHTLCRecoveryStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVHTLCRecoveryStatusRequest.ProtoReflect.Descriptor instead. func (*GetVHTLCRecoveryStatusRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{117} + return file_daemon_proto_rawDescGZIP(), []int{118} } func (x *GetVHTLCRecoveryStatusRequest) GetRecoveryId() string { @@ -10151,7 +10226,7 @@ type GetVHTLCRecoveryStatusResponse struct { func (x *GetVHTLCRecoveryStatusResponse) Reset() { *x = GetVHTLCRecoveryStatusResponse{} - mi := &file_daemon_proto_msgTypes[118] + mi := &file_daemon_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10163,7 +10238,7 @@ func (x *GetVHTLCRecoveryStatusResponse) String() string { func (*GetVHTLCRecoveryStatusResponse) ProtoMessage() {} func (x *GetVHTLCRecoveryStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[118] + mi := &file_daemon_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10176,7 +10251,7 @@ func (x *GetVHTLCRecoveryStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVHTLCRecoveryStatusResponse.ProtoReflect.Descriptor instead. func (*GetVHTLCRecoveryStatusResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{118} + return file_daemon_proto_rawDescGZIP(), []int{119} } func (x *GetVHTLCRecoveryStatusResponse) GetFound() bool { @@ -10203,7 +10278,7 @@ type ListVHTLCRecoveriesRequest struct { func (x *ListVHTLCRecoveriesRequest) Reset() { *x = ListVHTLCRecoveriesRequest{} - mi := &file_daemon_proto_msgTypes[119] + mi := &file_daemon_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10215,7 +10290,7 @@ func (x *ListVHTLCRecoveriesRequest) String() string { func (*ListVHTLCRecoveriesRequest) ProtoMessage() {} func (x *ListVHTLCRecoveriesRequest) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[119] + mi := &file_daemon_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10228,7 +10303,7 @@ func (x *ListVHTLCRecoveriesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListVHTLCRecoveriesRequest.ProtoReflect.Descriptor instead. func (*ListVHTLCRecoveriesRequest) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{119} + return file_daemon_proto_rawDescGZIP(), []int{120} } func (x *ListVHTLCRecoveriesRequest) GetIncludeTerminal() bool { @@ -10248,7 +10323,7 @@ type ListVHTLCRecoveriesResponse struct { func (x *ListVHTLCRecoveriesResponse) Reset() { *x = ListVHTLCRecoveriesResponse{} - mi := &file_daemon_proto_msgTypes[120] + mi := &file_daemon_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10260,7 +10335,7 @@ func (x *ListVHTLCRecoveriesResponse) String() string { func (*ListVHTLCRecoveriesResponse) ProtoMessage() {} func (x *ListVHTLCRecoveriesResponse) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[120] + mi := &file_daemon_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10273,7 +10348,7 @@ func (x *ListVHTLCRecoveriesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListVHTLCRecoveriesResponse.ProtoReflect.Descriptor instead. func (*ListVHTLCRecoveriesResponse) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{120} + return file_daemon_proto_rawDescGZIP(), []int{121} } func (x *ListVHTLCRecoveriesResponse) GetStatuses() []*VHTLCRecoveryStatus { @@ -10348,7 +10423,7 @@ type VHTLCRecoveryStatus struct { func (x *VHTLCRecoveryStatus) Reset() { *x = VHTLCRecoveryStatus{} - mi := &file_daemon_proto_msgTypes[121] + mi := &file_daemon_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10360,7 +10435,7 @@ func (x *VHTLCRecoveryStatus) String() string { func (*VHTLCRecoveryStatus) ProtoMessage() {} func (x *VHTLCRecoveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_daemon_proto_msgTypes[121] + mi := &file_daemon_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10373,7 +10448,7 @@ func (x *VHTLCRecoveryStatus) ProtoReflect() protoreflect.Message { // Deprecated: Use VHTLCRecoveryStatus.ProtoReflect.Descriptor instead. func (*VHTLCRecoveryStatus) Descriptor() ([]byte, []int) { - return file_daemon_proto_rawDescGZIP(), []int{121} + return file_daemon_proto_rawDescGZIP(), []int{122} } func (x *VHTLCRecoveryStatus) GetRecoveryId() string { @@ -10652,7 +10727,7 @@ const file_daemon_proto_rawDesc = "" + "\x0frelative_expiry\x18\a \x01(\rR\x0erelativeExpiry\x12$\n" + "\x0emax_tree_depth\x18\b \x01(\rR\fmaxTreeDepth\x12\x1f\n" + "\vchain_depth\x18\t \x01(\rR\n" + - "chainDepth\"\xb7\x04\n" + + "chainDepth\"\xf7\x04\n" + "\x04VTXO\x12\x1a\n" + "\boutpoint\x18\x01 \x01(\tR\boutpoint\x12\x1d\n" + "\n" + @@ -10673,7 +10748,12 @@ const file_daemon_proto_rawDesc = "" + "expiryInfo\x127\n" + "\n" + "settlement\x18\x0e \x01(\v2\x17.waverpc.VTXOSettlementR\n" + - "settlement\"U\n" + + "settlement\x12>\n" + + "\rtaproot_asset\x18\x0f \x01(\v2\x19.waverpc.VTXOTaprootAssetR\ftaprootAsset\"p\n" + + "\x10VTXOTaprootAsset\x12\x1b\n" + + "\tasset_ref\x18\x01 \x01(\tR\bassetRef\x12\x16\n" + + "\x06amount\x18\x02 \x01(\x04R\x06amount\x12'\n" + + "\x0fcommitment_root\x18\x03 \x01(\fR\x0ecommitmentRoot\"U\n" + "\x0eVTXOSettlement\x12\x12\n" + "\x04txid\x18\x01 \x01(\tR\x04txid\x12\x16\n" + "\x06height\x18\x02 \x01(\x05R\x06height\x12\x17\n" + @@ -11435,7 +11515,7 @@ func file_daemon_proto_rawDescGZIP() []byte { } var file_daemon_proto_enumTypes = make([]protoimpl.EnumInfo, 12) -var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 123) +var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 124) var file_daemon_proto_goTypes = []any{ (TaprootAssetOnboardingState)(0), // 0: waverpc.TaprootAssetOnboardingState (WalletState)(0), // 1: waverpc.WalletState @@ -11464,114 +11544,115 @@ var file_daemon_proto_goTypes = []any{ (*GetBalanceResponse)(nil), // 24: waverpc.GetBalanceResponse (*VTXOExpiryInfo)(nil), // 25: waverpc.VTXOExpiryInfo (*VTXO)(nil), // 26: waverpc.VTXO - (*VTXOSettlement)(nil), // 27: waverpc.VTXOSettlement - (*ListVTXOsRequest)(nil), // 28: waverpc.ListVTXOsRequest - (*ListVTXOsResponse)(nil), // 29: waverpc.ListVTXOsResponse - (*NewAddressRequest)(nil), // 30: waverpc.NewAddressRequest - (*NewAddressResponse)(nil), // 31: waverpc.NewAddressResponse - (*NewReceiveScriptRequest)(nil), // 32: waverpc.NewReceiveScriptRequest - (*NewReceiveScriptResponse)(nil), // 33: waverpc.NewReceiveScriptResponse - (*ReceiveAuthKeyRequest)(nil), // 34: waverpc.ReceiveAuthKeyRequest - (*ReceiveAuthKeyResponse)(nil), // 35: waverpc.ReceiveAuthKeyResponse - (*SignReceiveAuthMessageRequest)(nil), // 36: waverpc.SignReceiveAuthMessageRequest - (*SignReceiveAuthMessageResponse)(nil), // 37: waverpc.SignReceiveAuthMessageResponse - (*SignReceiveAuthMessageCompactRequest)(nil), // 38: waverpc.SignReceiveAuthMessageCompactRequest - (*SignReceiveAuthMessageCompactResponse)(nil), // 39: waverpc.SignReceiveAuthMessageCompactResponse - (*ReceiveAuthECDHRequest)(nil), // 40: waverpc.ReceiveAuthECDHRequest - (*ReceiveAuthECDHResponse)(nil), // 41: waverpc.ReceiveAuthECDHResponse - (*GetIndexedVTXOByPkScriptRequest)(nil), // 42: waverpc.GetIndexedVTXOByPkScriptRequest - (*GetIndexedVTXOByPkScriptResponse)(nil), // 43: waverpc.GetIndexedVTXOByPkScriptResponse - (*GetVTXOExpiryInfoRequest)(nil), // 44: waverpc.GetVTXOExpiryInfoRequest - (*GetVTXOExpiryInfoResponse)(nil), // 45: waverpc.GetVTXOExpiryInfoResponse - (*GetIndexedOORSessionByTxidRequest)(nil), // 46: waverpc.GetIndexedOORSessionByTxidRequest - (*GetIndexedOORSessionByTxidResponse)(nil), // 47: waverpc.GetIndexedOORSessionByTxidResponse - (*Output)(nil), // 48: waverpc.Output - (*SendVTXORequest)(nil), // 49: waverpc.SendVTXORequest - (*SendVTXOResponse)(nil), // 50: waverpc.SendVTXOResponse - (*SendOORRequest)(nil), // 51: waverpc.SendOORRequest - (*TaprootAssetOORIntent)(nil), // 52: waverpc.TaprootAssetOORIntent - (*CustomOORInput)(nil), // 53: waverpc.CustomOORInput - (*TaprootScriptSignature)(nil), // 54: waverpc.TaprootScriptSignature - (*SendOORResponse)(nil), // 55: waverpc.SendOORResponse - (*PrepareOORRequest)(nil), // 56: waverpc.PrepareOORRequest - (*PreparedOORCustomInput)(nil), // 57: waverpc.PreparedOORCustomInput - (*PrepareOORResponse)(nil), // 58: waverpc.PrepareOORResponse - (*SignOORCustomInputRequest)(nil), // 59: waverpc.SignOORCustomInputRequest - (*SignOORCustomInputResponse)(nil), // 60: waverpc.SignOORCustomInputResponse - (*SignVTXOForfeitRequest)(nil), // 61: waverpc.SignVTXOForfeitRequest - (*SignVTXOForfeitResponse)(nil), // 62: waverpc.SignVTXOForfeitResponse - (*ForfeitSigningContext)(nil), // 63: waverpc.ForfeitSigningContext - (*OutpointSelection)(nil), // 64: waverpc.OutpointSelection - (*RefreshVTXOsRequest)(nil), // 65: waverpc.RefreshVTXOsRequest - (*RefreshVTXOsResponse)(nil), // 66: waverpc.RefreshVTXOsResponse - (*RefreshFeeEstimate)(nil), // 67: waverpc.RefreshFeeEstimate - (*OutpointFeeEstimate)(nil), // 68: waverpc.OutpointFeeEstimate - (*CustomRefreshVTXOInput)(nil), // 69: waverpc.CustomRefreshVTXOInput - (*CustomRefreshVTXOOutput)(nil), // 70: waverpc.CustomRefreshVTXOOutput - (*RefreshCustomVTXOsRequest)(nil), // 71: waverpc.RefreshCustomVTXOsRequest - (*RefreshCustomVTXOsResponse)(nil), // 72: waverpc.RefreshCustomVTXOsResponse - (*PendingForfeitParticipantSignatureRequest)(nil), // 73: waverpc.PendingForfeitParticipantSignatureRequest - (*ListPendingForfeitParticipantSignatureRequestsRequest)(nil), // 74: waverpc.ListPendingForfeitParticipantSignatureRequestsRequest - (*ListPendingForfeitParticipantSignatureRequestsResponse)(nil), // 75: waverpc.ListPendingForfeitParticipantSignatureRequestsResponse - (*ForfeitParticipantSignature)(nil), // 76: waverpc.ForfeitParticipantSignature - (*SubmitForfeitParticipantSignaturesRequest)(nil), // 77: waverpc.SubmitForfeitParticipantSignaturesRequest - (*SubmitForfeitParticipantSignaturesResponse)(nil), // 78: waverpc.SubmitForfeitParticipantSignaturesResponse - (*LeaveDestination)(nil), // 79: waverpc.LeaveDestination - (*LeaveVTXOsRequest)(nil), // 80: waverpc.LeaveVTXOsRequest - (*LeaveVTXOsResponse)(nil), // 81: waverpc.LeaveVTXOsResponse - (*SendOnChainRequest)(nil), // 82: waverpc.SendOnChainRequest - (*SendOnChainResponse)(nil), // 83: waverpc.SendOnChainResponse - (*BoardRequest)(nil), // 84: waverpc.BoardRequest - (*BoardResponse)(nil), // 85: waverpc.BoardResponse - (*JoinNextRoundRequest)(nil), // 86: waverpc.JoinNextRoundRequest - (*JoinNextRoundResponse)(nil), // 87: waverpc.JoinNextRoundResponse - (*SweepBoardingUTXOsRequest)(nil), // 88: waverpc.SweepBoardingUTXOsRequest - (*BoardingSweepOutput)(nil), // 89: waverpc.BoardingSweepOutput - (*SweepBoardingUTXOsResponse)(nil), // 90: waverpc.SweepBoardingUTXOsResponse - (*ListBoardingSweepsRequest)(nil), // 91: waverpc.ListBoardingSweepsRequest - (*BoardingSweepInput)(nil), // 92: waverpc.BoardingSweepInput - (*BoardingSweep)(nil), // 93: waverpc.BoardingSweep - (*ListBoardingSweepsResponse)(nil), // 94: waverpc.ListBoardingSweepsResponse - (*RoundVTXOInfo)(nil), // 95: waverpc.RoundVTXOInfo - (*RoundInfo)(nil), // 96: waverpc.RoundInfo - (*ListRoundsRequest)(nil), // 97: waverpc.ListRoundsRequest - (*GetRoundRequest)(nil), // 98: waverpc.GetRoundRequest - (*GetRoundResponse)(nil), // 99: waverpc.GetRoundResponse - (*ListRoundsResponse)(nil), // 100: waverpc.ListRoundsResponse - (*WatchRoundsRequest)(nil), // 101: waverpc.WatchRoundsRequest - (*WatchRoundsResponse)(nil), // 102: waverpc.WatchRoundsResponse - (*OORSessionInfo)(nil), // 103: waverpc.OORSessionInfo - (*ListOORSessionsRequest)(nil), // 104: waverpc.ListOORSessionsRequest - (*ListOORSessionsResponse)(nil), // 105: waverpc.ListOORSessionsResponse - (*GetOORSessionRequest)(nil), // 106: waverpc.GetOORSessionRequest - (*GetOORSessionResponse)(nil), // 107: waverpc.GetOORSessionResponse - (*EstimateFeeRequest)(nil), // 108: waverpc.EstimateFeeRequest - (*EstimateFeeResponse)(nil), // 109: waverpc.EstimateFeeResponse - (*GetFeeHistoryRequest)(nil), // 110: waverpc.GetFeeHistoryRequest - (*FeeHistoryEntry)(nil), // 111: waverpc.FeeHistoryEntry - (*GetFeeHistoryResponse)(nil), // 112: waverpc.GetFeeHistoryResponse - (*ListTransactionsRequest)(nil), // 113: waverpc.ListTransactionsRequest - (*TransactionHistoryEntry)(nil), // 114: waverpc.TransactionHistoryEntry - (*ListTransactionsResponse)(nil), // 115: waverpc.ListTransactionsResponse - (*UnrollRequest)(nil), // 116: waverpc.UnrollRequest - (*UnrollResponse)(nil), // 117: waverpc.UnrollResponse - (*GetUnrollStatusRequest)(nil), // 118: waverpc.GetUnrollStatusRequest - (*UnrollProgress)(nil), // 119: waverpc.UnrollProgress - (*UnrollCSV)(nil), // 120: waverpc.UnrollCSV - (*UnrollFees)(nil), // 121: waverpc.UnrollFees - (*GetUnrollStatusResponse)(nil), // 122: waverpc.GetUnrollStatusResponse - (*ArmVHTLCRecoveryRequest)(nil), // 123: waverpc.ArmVHTLCRecoveryRequest - (*ArmVHTLCRecoveryResponse)(nil), // 124: waverpc.ArmVHTLCRecoveryResponse - (*EscalateVHTLCRecoveryRequest)(nil), // 125: waverpc.EscalateVHTLCRecoveryRequest - (*EscalateVHTLCRecoveryResponse)(nil), // 126: waverpc.EscalateVHTLCRecoveryResponse - (*CancelVHTLCRecoveryRequest)(nil), // 127: waverpc.CancelVHTLCRecoveryRequest - (*CancelVHTLCRecoveryResponse)(nil), // 128: waverpc.CancelVHTLCRecoveryResponse - (*GetVHTLCRecoveryStatusRequest)(nil), // 129: waverpc.GetVHTLCRecoveryStatusRequest - (*GetVHTLCRecoveryStatusResponse)(nil), // 130: waverpc.GetVHTLCRecoveryStatusResponse - (*ListVHTLCRecoveriesRequest)(nil), // 131: waverpc.ListVHTLCRecoveriesRequest - (*ListVHTLCRecoveriesResponse)(nil), // 132: waverpc.ListVHTLCRecoveriesResponse - (*VHTLCRecoveryStatus)(nil), // 133: waverpc.VHTLCRecoveryStatus - nil, // 134: waverpc.LeaveVTXOsRequest.DestinationsEntry + (*VTXOTaprootAsset)(nil), // 27: waverpc.VTXOTaprootAsset + (*VTXOSettlement)(nil), // 28: waverpc.VTXOSettlement + (*ListVTXOsRequest)(nil), // 29: waverpc.ListVTXOsRequest + (*ListVTXOsResponse)(nil), // 30: waverpc.ListVTXOsResponse + (*NewAddressRequest)(nil), // 31: waverpc.NewAddressRequest + (*NewAddressResponse)(nil), // 32: waverpc.NewAddressResponse + (*NewReceiveScriptRequest)(nil), // 33: waverpc.NewReceiveScriptRequest + (*NewReceiveScriptResponse)(nil), // 34: waverpc.NewReceiveScriptResponse + (*ReceiveAuthKeyRequest)(nil), // 35: waverpc.ReceiveAuthKeyRequest + (*ReceiveAuthKeyResponse)(nil), // 36: waverpc.ReceiveAuthKeyResponse + (*SignReceiveAuthMessageRequest)(nil), // 37: waverpc.SignReceiveAuthMessageRequest + (*SignReceiveAuthMessageResponse)(nil), // 38: waverpc.SignReceiveAuthMessageResponse + (*SignReceiveAuthMessageCompactRequest)(nil), // 39: waverpc.SignReceiveAuthMessageCompactRequest + (*SignReceiveAuthMessageCompactResponse)(nil), // 40: waverpc.SignReceiveAuthMessageCompactResponse + (*ReceiveAuthECDHRequest)(nil), // 41: waverpc.ReceiveAuthECDHRequest + (*ReceiveAuthECDHResponse)(nil), // 42: waverpc.ReceiveAuthECDHResponse + (*GetIndexedVTXOByPkScriptRequest)(nil), // 43: waverpc.GetIndexedVTXOByPkScriptRequest + (*GetIndexedVTXOByPkScriptResponse)(nil), // 44: waverpc.GetIndexedVTXOByPkScriptResponse + (*GetVTXOExpiryInfoRequest)(nil), // 45: waverpc.GetVTXOExpiryInfoRequest + (*GetVTXOExpiryInfoResponse)(nil), // 46: waverpc.GetVTXOExpiryInfoResponse + (*GetIndexedOORSessionByTxidRequest)(nil), // 47: waverpc.GetIndexedOORSessionByTxidRequest + (*GetIndexedOORSessionByTxidResponse)(nil), // 48: waverpc.GetIndexedOORSessionByTxidResponse + (*Output)(nil), // 49: waverpc.Output + (*SendVTXORequest)(nil), // 50: waverpc.SendVTXORequest + (*SendVTXOResponse)(nil), // 51: waverpc.SendVTXOResponse + (*SendOORRequest)(nil), // 52: waverpc.SendOORRequest + (*TaprootAssetOORIntent)(nil), // 53: waverpc.TaprootAssetOORIntent + (*CustomOORInput)(nil), // 54: waverpc.CustomOORInput + (*TaprootScriptSignature)(nil), // 55: waverpc.TaprootScriptSignature + (*SendOORResponse)(nil), // 56: waverpc.SendOORResponse + (*PrepareOORRequest)(nil), // 57: waverpc.PrepareOORRequest + (*PreparedOORCustomInput)(nil), // 58: waverpc.PreparedOORCustomInput + (*PrepareOORResponse)(nil), // 59: waverpc.PrepareOORResponse + (*SignOORCustomInputRequest)(nil), // 60: waverpc.SignOORCustomInputRequest + (*SignOORCustomInputResponse)(nil), // 61: waverpc.SignOORCustomInputResponse + (*SignVTXOForfeitRequest)(nil), // 62: waverpc.SignVTXOForfeitRequest + (*SignVTXOForfeitResponse)(nil), // 63: waverpc.SignVTXOForfeitResponse + (*ForfeitSigningContext)(nil), // 64: waverpc.ForfeitSigningContext + (*OutpointSelection)(nil), // 65: waverpc.OutpointSelection + (*RefreshVTXOsRequest)(nil), // 66: waverpc.RefreshVTXOsRequest + (*RefreshVTXOsResponse)(nil), // 67: waverpc.RefreshVTXOsResponse + (*RefreshFeeEstimate)(nil), // 68: waverpc.RefreshFeeEstimate + (*OutpointFeeEstimate)(nil), // 69: waverpc.OutpointFeeEstimate + (*CustomRefreshVTXOInput)(nil), // 70: waverpc.CustomRefreshVTXOInput + (*CustomRefreshVTXOOutput)(nil), // 71: waverpc.CustomRefreshVTXOOutput + (*RefreshCustomVTXOsRequest)(nil), // 72: waverpc.RefreshCustomVTXOsRequest + (*RefreshCustomVTXOsResponse)(nil), // 73: waverpc.RefreshCustomVTXOsResponse + (*PendingForfeitParticipantSignatureRequest)(nil), // 74: waverpc.PendingForfeitParticipantSignatureRequest + (*ListPendingForfeitParticipantSignatureRequestsRequest)(nil), // 75: waverpc.ListPendingForfeitParticipantSignatureRequestsRequest + (*ListPendingForfeitParticipantSignatureRequestsResponse)(nil), // 76: waverpc.ListPendingForfeitParticipantSignatureRequestsResponse + (*ForfeitParticipantSignature)(nil), // 77: waverpc.ForfeitParticipantSignature + (*SubmitForfeitParticipantSignaturesRequest)(nil), // 78: waverpc.SubmitForfeitParticipantSignaturesRequest + (*SubmitForfeitParticipantSignaturesResponse)(nil), // 79: waverpc.SubmitForfeitParticipantSignaturesResponse + (*LeaveDestination)(nil), // 80: waverpc.LeaveDestination + (*LeaveVTXOsRequest)(nil), // 81: waverpc.LeaveVTXOsRequest + (*LeaveVTXOsResponse)(nil), // 82: waverpc.LeaveVTXOsResponse + (*SendOnChainRequest)(nil), // 83: waverpc.SendOnChainRequest + (*SendOnChainResponse)(nil), // 84: waverpc.SendOnChainResponse + (*BoardRequest)(nil), // 85: waverpc.BoardRequest + (*BoardResponse)(nil), // 86: waverpc.BoardResponse + (*JoinNextRoundRequest)(nil), // 87: waverpc.JoinNextRoundRequest + (*JoinNextRoundResponse)(nil), // 88: waverpc.JoinNextRoundResponse + (*SweepBoardingUTXOsRequest)(nil), // 89: waverpc.SweepBoardingUTXOsRequest + (*BoardingSweepOutput)(nil), // 90: waverpc.BoardingSweepOutput + (*SweepBoardingUTXOsResponse)(nil), // 91: waverpc.SweepBoardingUTXOsResponse + (*ListBoardingSweepsRequest)(nil), // 92: waverpc.ListBoardingSweepsRequest + (*BoardingSweepInput)(nil), // 93: waverpc.BoardingSweepInput + (*BoardingSweep)(nil), // 94: waverpc.BoardingSweep + (*ListBoardingSweepsResponse)(nil), // 95: waverpc.ListBoardingSweepsResponse + (*RoundVTXOInfo)(nil), // 96: waverpc.RoundVTXOInfo + (*RoundInfo)(nil), // 97: waverpc.RoundInfo + (*ListRoundsRequest)(nil), // 98: waverpc.ListRoundsRequest + (*GetRoundRequest)(nil), // 99: waverpc.GetRoundRequest + (*GetRoundResponse)(nil), // 100: waverpc.GetRoundResponse + (*ListRoundsResponse)(nil), // 101: waverpc.ListRoundsResponse + (*WatchRoundsRequest)(nil), // 102: waverpc.WatchRoundsRequest + (*WatchRoundsResponse)(nil), // 103: waverpc.WatchRoundsResponse + (*OORSessionInfo)(nil), // 104: waverpc.OORSessionInfo + (*ListOORSessionsRequest)(nil), // 105: waverpc.ListOORSessionsRequest + (*ListOORSessionsResponse)(nil), // 106: waverpc.ListOORSessionsResponse + (*GetOORSessionRequest)(nil), // 107: waverpc.GetOORSessionRequest + (*GetOORSessionResponse)(nil), // 108: waverpc.GetOORSessionResponse + (*EstimateFeeRequest)(nil), // 109: waverpc.EstimateFeeRequest + (*EstimateFeeResponse)(nil), // 110: waverpc.EstimateFeeResponse + (*GetFeeHistoryRequest)(nil), // 111: waverpc.GetFeeHistoryRequest + (*FeeHistoryEntry)(nil), // 112: waverpc.FeeHistoryEntry + (*GetFeeHistoryResponse)(nil), // 113: waverpc.GetFeeHistoryResponse + (*ListTransactionsRequest)(nil), // 114: waverpc.ListTransactionsRequest + (*TransactionHistoryEntry)(nil), // 115: waverpc.TransactionHistoryEntry + (*ListTransactionsResponse)(nil), // 116: waverpc.ListTransactionsResponse + (*UnrollRequest)(nil), // 117: waverpc.UnrollRequest + (*UnrollResponse)(nil), // 118: waverpc.UnrollResponse + (*GetUnrollStatusRequest)(nil), // 119: waverpc.GetUnrollStatusRequest + (*UnrollProgress)(nil), // 120: waverpc.UnrollProgress + (*UnrollCSV)(nil), // 121: waverpc.UnrollCSV + (*UnrollFees)(nil), // 122: waverpc.UnrollFees + (*GetUnrollStatusResponse)(nil), // 123: waverpc.GetUnrollStatusResponse + (*ArmVHTLCRecoveryRequest)(nil), // 124: waverpc.ArmVHTLCRecoveryRequest + (*ArmVHTLCRecoveryResponse)(nil), // 125: waverpc.ArmVHTLCRecoveryResponse + (*EscalateVHTLCRecoveryRequest)(nil), // 126: waverpc.EscalateVHTLCRecoveryRequest + (*EscalateVHTLCRecoveryResponse)(nil), // 127: waverpc.EscalateVHTLCRecoveryResponse + (*CancelVHTLCRecoveryRequest)(nil), // 128: waverpc.CancelVHTLCRecoveryRequest + (*CancelVHTLCRecoveryResponse)(nil), // 129: waverpc.CancelVHTLCRecoveryResponse + (*GetVHTLCRecoveryStatusRequest)(nil), // 130: waverpc.GetVHTLCRecoveryStatusRequest + (*GetVHTLCRecoveryStatusResponse)(nil), // 131: waverpc.GetVHTLCRecoveryStatusResponse + (*ListVHTLCRecoveriesRequest)(nil), // 132: waverpc.ListVHTLCRecoveriesRequest + (*ListVHTLCRecoveriesResponse)(nil), // 133: waverpc.ListVHTLCRecoveriesResponse + (*VHTLCRecoveryStatus)(nil), // 134: waverpc.VHTLCRecoveryStatus + nil, // 135: waverpc.LeaveVTXOsRequest.DestinationsEntry } var file_daemon_proto_depIdxs = []int32{ 0, // 0: waverpc.OnboardTaprootAssetResponse.state:type_name -> waverpc.TaprootAssetOnboardingState @@ -11580,168 +11661,169 @@ var file_daemon_proto_depIdxs = []int32{ 3, // 3: waverpc.VTXOExpiryInfo.status:type_name -> waverpc.VTXOExpiryStatus 2, // 4: waverpc.VTXO.status:type_name -> waverpc.VTXOStatus 25, // 5: waverpc.VTXO.expiry_info:type_name -> waverpc.VTXOExpiryInfo - 27, // 6: waverpc.VTXO.settlement:type_name -> waverpc.VTXOSettlement - 2, // 7: waverpc.ListVTXOsRequest.status_filter:type_name -> waverpc.VTXOStatus - 26, // 8: waverpc.ListVTXOsResponse.vtxos:type_name -> waverpc.VTXO - 2, // 9: waverpc.GetIndexedVTXOByPkScriptRequest.status_filter:type_name -> waverpc.VTXOStatus - 26, // 10: waverpc.GetIndexedVTXOByPkScriptResponse.vtxo:type_name -> waverpc.VTXO - 2, // 11: waverpc.GetVTXOExpiryInfoRequest.status_filter:type_name -> waverpc.VTXOStatus - 25, // 12: waverpc.GetVTXOExpiryInfoResponse.expiry_info:type_name -> waverpc.VTXOExpiryInfo - 26, // 13: waverpc.GetVTXOExpiryInfoResponse.vtxo:type_name -> waverpc.VTXO - 48, // 14: waverpc.SendVTXORequest.recipients:type_name -> waverpc.Output - 48, // 15: waverpc.SendOORRequest.recipients:type_name -> waverpc.Output - 53, // 16: waverpc.SendOORRequest.custom_inputs:type_name -> waverpc.CustomOORInput - 52, // 17: waverpc.SendOORRequest.taproot_asset:type_name -> waverpc.TaprootAssetOORIntent - 54, // 18: waverpc.CustomOORInput.external_signatures:type_name -> waverpc.TaprootScriptSignature - 48, // 19: waverpc.PrepareOORRequest.recipient:type_name -> waverpc.Output - 53, // 20: waverpc.PrepareOORRequest.custom_inputs:type_name -> waverpc.CustomOORInput - 57, // 21: waverpc.PrepareOORResponse.custom_inputs:type_name -> waverpc.PreparedOORCustomInput - 53, // 22: waverpc.SignOORCustomInputRequest.custom_input:type_name -> waverpc.CustomOORInput - 54, // 23: waverpc.SignOORCustomInputResponse.signature:type_name -> waverpc.TaprootScriptSignature - 4, // 24: waverpc.ForfeitSigningContext.signing_route:type_name -> waverpc.ForfeitSigningRoute - 64, // 25: waverpc.RefreshVTXOsRequest.outpoints:type_name -> waverpc.OutpointSelection - 67, // 26: waverpc.RefreshVTXOsResponse.fee_estimate:type_name -> waverpc.RefreshFeeEstimate - 68, // 27: waverpc.RefreshFeeEstimate.outpoints:type_name -> waverpc.OutpointFeeEstimate - 63, // 28: waverpc.CustomRefreshVTXOInput.forfeit_signing_context:type_name -> waverpc.ForfeitSigningContext - 69, // 29: waverpc.RefreshCustomVTXOsRequest.inputs:type_name -> waverpc.CustomRefreshVTXOInput - 70, // 30: waverpc.RefreshCustomVTXOsRequest.outputs:type_name -> waverpc.CustomRefreshVTXOOutput - 4, // 31: waverpc.PendingForfeitParticipantSignatureRequest.signing_route:type_name -> waverpc.ForfeitSigningRoute - 73, // 32: waverpc.ListPendingForfeitParticipantSignatureRequestsResponse.requests:type_name -> waverpc.PendingForfeitParticipantSignatureRequest - 76, // 33: waverpc.SubmitForfeitParticipantSignaturesRequest.signatures:type_name -> waverpc.ForfeitParticipantSignature - 64, // 34: waverpc.LeaveVTXOsRequest.outpoints:type_name -> waverpc.OutpointSelection - 79, // 35: waverpc.LeaveVTXOsRequest.default_destination:type_name -> waverpc.LeaveDestination - 134, // 36: waverpc.LeaveVTXOsRequest.destinations:type_name -> waverpc.LeaveVTXOsRequest.DestinationsEntry - 79, // 37: waverpc.SendOnChainRequest.destination:type_name -> waverpc.LeaveDestination - 89, // 38: waverpc.SweepBoardingUTXOsResponse.sweepable_outputs:type_name -> waverpc.BoardingSweepOutput - 92, // 39: waverpc.BoardingSweep.inputs:type_name -> waverpc.BoardingSweepInput - 93, // 40: waverpc.ListBoardingSweepsResponse.sweeps:type_name -> waverpc.BoardingSweep - 5, // 41: waverpc.RoundInfo.state:type_name -> waverpc.RoundState - 95, // 42: waverpc.RoundInfo.vtxos:type_name -> waverpc.RoundVTXOInfo - 5, // 43: waverpc.ListRoundsRequest.state_filter:type_name -> waverpc.RoundState - 96, // 44: waverpc.GetRoundResponse.round:type_name -> waverpc.RoundInfo - 96, // 45: waverpc.ListRoundsResponse.rounds:type_name -> waverpc.RoundInfo - 96, // 46: waverpc.WatchRoundsResponse.round:type_name -> waverpc.RoundInfo - 6, // 47: waverpc.OORSessionInfo.direction:type_name -> waverpc.OORSessionDirection - 7, // 48: waverpc.OORSessionInfo.status:type_name -> waverpc.OORSessionStatus - 6, // 49: waverpc.ListOORSessionsRequest.direction_filter:type_name -> waverpc.OORSessionDirection - 7, // 50: waverpc.ListOORSessionsRequest.status_filter:type_name -> waverpc.OORSessionStatus - 103, // 51: waverpc.ListOORSessionsResponse.sessions:type_name -> waverpc.OORSessionInfo - 103, // 52: waverpc.GetOORSessionResponse.session:type_name -> waverpc.OORSessionInfo - 111, // 53: waverpc.GetFeeHistoryResponse.entries:type_name -> waverpc.FeeHistoryEntry - 114, // 54: waverpc.ListTransactionsResponse.transactions:type_name -> waverpc.TransactionHistoryEntry - 8, // 55: waverpc.GetUnrollStatusResponse.status:type_name -> waverpc.UnrollJobStatus - 119, // 56: waverpc.GetUnrollStatusResponse.progress:type_name -> waverpc.UnrollProgress - 120, // 57: waverpc.GetUnrollStatusResponse.csv:type_name -> waverpc.UnrollCSV - 121, // 58: waverpc.GetUnrollStatusResponse.fees:type_name -> waverpc.UnrollFees - 9, // 59: waverpc.ArmVHTLCRecoveryRequest.direction:type_name -> waverpc.VHTLCRecoveryDirection - 10, // 60: waverpc.ArmVHTLCRecoveryRequest.action:type_name -> waverpc.VHTLCRecoveryAction - 133, // 61: waverpc.ArmVHTLCRecoveryResponse.status:type_name -> waverpc.VHTLCRecoveryStatus - 133, // 62: waverpc.EscalateVHTLCRecoveryResponse.status:type_name -> waverpc.VHTLCRecoveryStatus - 133, // 63: waverpc.CancelVHTLCRecoveryResponse.status:type_name -> waverpc.VHTLCRecoveryStatus - 133, // 64: waverpc.GetVHTLCRecoveryStatusResponse.status:type_name -> waverpc.VHTLCRecoveryStatus - 133, // 65: waverpc.ListVHTLCRecoveriesResponse.statuses:type_name -> waverpc.VHTLCRecoveryStatus - 9, // 66: waverpc.VHTLCRecoveryStatus.direction:type_name -> waverpc.VHTLCRecoveryDirection - 10, // 67: waverpc.VHTLCRecoveryStatus.action:type_name -> waverpc.VHTLCRecoveryAction - 11, // 68: waverpc.VHTLCRecoveryStatus.state:type_name -> waverpc.VHTLCRecoveryState - 8, // 69: waverpc.VHTLCRecoveryStatus.unroll_status:type_name -> waverpc.UnrollJobStatus - 79, // 70: waverpc.LeaveVTXOsRequest.DestinationsEntry.value:type_name -> waverpc.LeaveDestination - 14, // 71: waverpc.DaemonService.GetInfo:input_type -> waverpc.GetInfoRequest - 17, // 72: waverpc.DaemonService.GenSeed:input_type -> waverpc.GenSeedRequest - 19, // 73: waverpc.DaemonService.InitWallet:input_type -> waverpc.InitWalletRequest - 21, // 74: waverpc.DaemonService.UnlockWallet:input_type -> waverpc.UnlockWalletRequest - 23, // 75: waverpc.DaemonService.GetBalance:input_type -> waverpc.GetBalanceRequest - 28, // 76: waverpc.DaemonService.ListVTXOs:input_type -> waverpc.ListVTXOsRequest - 30, // 77: waverpc.DaemonService.NewAddress:input_type -> waverpc.NewAddressRequest - 32, // 78: waverpc.DaemonService.NewReceiveScript:input_type -> waverpc.NewReceiveScriptRequest - 34, // 79: waverpc.DaemonService.ReceiveAuthKey:input_type -> waverpc.ReceiveAuthKeyRequest - 36, // 80: waverpc.DaemonService.SignReceiveAuthMessage:input_type -> waverpc.SignReceiveAuthMessageRequest - 38, // 81: waverpc.DaemonService.SignReceiveAuthMessageCompact:input_type -> waverpc.SignReceiveAuthMessageCompactRequest - 40, // 82: waverpc.DaemonService.ReceiveAuthECDH:input_type -> waverpc.ReceiveAuthECDHRequest - 42, // 83: waverpc.DaemonService.GetIndexedVTXOByPkScript:input_type -> waverpc.GetIndexedVTXOByPkScriptRequest - 44, // 84: waverpc.DaemonService.GetVTXOExpiryInfo:input_type -> waverpc.GetVTXOExpiryInfoRequest - 46, // 85: waverpc.DaemonService.GetIndexedOORSessionByTxid:input_type -> waverpc.GetIndexedOORSessionByTxidRequest - 49, // 86: waverpc.DaemonService.SendVTXO:input_type -> waverpc.SendVTXORequest - 51, // 87: waverpc.DaemonService.SendOOR:input_type -> waverpc.SendOORRequest - 12, // 88: waverpc.DaemonService.OnboardTaprootAsset:input_type -> waverpc.OnboardTaprootAssetRequest - 56, // 89: waverpc.DaemonService.PrepareOOR:input_type -> waverpc.PrepareOORRequest - 59, // 90: waverpc.DaemonService.SignOORCustomInput:input_type -> waverpc.SignOORCustomInputRequest - 61, // 91: waverpc.DaemonService.SignVTXOForfeit:input_type -> waverpc.SignVTXOForfeitRequest - 65, // 92: waverpc.DaemonService.RefreshVTXOs:input_type -> waverpc.RefreshVTXOsRequest - 71, // 93: waverpc.DaemonService.RefreshCustomVTXOs:input_type -> waverpc.RefreshCustomVTXOsRequest - 74, // 94: waverpc.DaemonService.ListPendingForfeitParticipantSignatureRequests:input_type -> waverpc.ListPendingForfeitParticipantSignatureRequestsRequest - 77, // 95: waverpc.DaemonService.SubmitForfeitParticipantSignatures:input_type -> waverpc.SubmitForfeitParticipantSignaturesRequest - 80, // 96: waverpc.DaemonService.LeaveVTXOs:input_type -> waverpc.LeaveVTXOsRequest - 82, // 97: waverpc.DaemonService.SendOnChain:input_type -> waverpc.SendOnChainRequest - 84, // 98: waverpc.DaemonService.Board:input_type -> waverpc.BoardRequest - 86, // 99: waverpc.DaemonService.JoinNextRound:input_type -> waverpc.JoinNextRoundRequest - 88, // 100: waverpc.DaemonService.SweepBoardingUTXOs:input_type -> waverpc.SweepBoardingUTXOsRequest - 91, // 101: waverpc.DaemonService.ListBoardingSweeps:input_type -> waverpc.ListBoardingSweepsRequest - 97, // 102: waverpc.DaemonService.ListRounds:input_type -> waverpc.ListRoundsRequest - 98, // 103: waverpc.DaemonService.GetRound:input_type -> waverpc.GetRoundRequest - 101, // 104: waverpc.DaemonService.WatchRounds:input_type -> waverpc.WatchRoundsRequest - 104, // 105: waverpc.DaemonService.ListOORSessions:input_type -> waverpc.ListOORSessionsRequest - 106, // 106: waverpc.DaemonService.GetOORSession:input_type -> waverpc.GetOORSessionRequest - 108, // 107: waverpc.DaemonService.EstimateFee:input_type -> waverpc.EstimateFeeRequest - 110, // 108: waverpc.DaemonService.GetFeeHistory:input_type -> waverpc.GetFeeHistoryRequest - 113, // 109: waverpc.DaemonService.ListTransactions:input_type -> waverpc.ListTransactionsRequest - 116, // 110: waverpc.DaemonService.Unroll:input_type -> waverpc.UnrollRequest - 118, // 111: waverpc.DaemonService.GetUnrollStatus:input_type -> waverpc.GetUnrollStatusRequest - 123, // 112: waverpc.DaemonService.ArmVHTLCRecovery:input_type -> waverpc.ArmVHTLCRecoveryRequest - 125, // 113: waverpc.DaemonService.EscalateVHTLCRecovery:input_type -> waverpc.EscalateVHTLCRecoveryRequest - 127, // 114: waverpc.DaemonService.CancelVHTLCRecovery:input_type -> waverpc.CancelVHTLCRecoveryRequest - 129, // 115: waverpc.DaemonService.GetVHTLCRecoveryStatus:input_type -> waverpc.GetVHTLCRecoveryStatusRequest - 131, // 116: waverpc.DaemonService.ListVHTLCRecoveries:input_type -> waverpc.ListVHTLCRecoveriesRequest - 15, // 117: waverpc.DaemonService.GetInfo:output_type -> waverpc.GetInfoResponse - 18, // 118: waverpc.DaemonService.GenSeed:output_type -> waverpc.GenSeedResponse - 20, // 119: waverpc.DaemonService.InitWallet:output_type -> waverpc.InitWalletResponse - 22, // 120: waverpc.DaemonService.UnlockWallet:output_type -> waverpc.UnlockWalletResponse - 24, // 121: waverpc.DaemonService.GetBalance:output_type -> waverpc.GetBalanceResponse - 29, // 122: waverpc.DaemonService.ListVTXOs:output_type -> waverpc.ListVTXOsResponse - 31, // 123: waverpc.DaemonService.NewAddress:output_type -> waverpc.NewAddressResponse - 33, // 124: waverpc.DaemonService.NewReceiveScript:output_type -> waverpc.NewReceiveScriptResponse - 35, // 125: waverpc.DaemonService.ReceiveAuthKey:output_type -> waverpc.ReceiveAuthKeyResponse - 37, // 126: waverpc.DaemonService.SignReceiveAuthMessage:output_type -> waverpc.SignReceiveAuthMessageResponse - 39, // 127: waverpc.DaemonService.SignReceiveAuthMessageCompact:output_type -> waverpc.SignReceiveAuthMessageCompactResponse - 41, // 128: waverpc.DaemonService.ReceiveAuthECDH:output_type -> waverpc.ReceiveAuthECDHResponse - 43, // 129: waverpc.DaemonService.GetIndexedVTXOByPkScript:output_type -> waverpc.GetIndexedVTXOByPkScriptResponse - 45, // 130: waverpc.DaemonService.GetVTXOExpiryInfo:output_type -> waverpc.GetVTXOExpiryInfoResponse - 47, // 131: waverpc.DaemonService.GetIndexedOORSessionByTxid:output_type -> waverpc.GetIndexedOORSessionByTxidResponse - 50, // 132: waverpc.DaemonService.SendVTXO:output_type -> waverpc.SendVTXOResponse - 55, // 133: waverpc.DaemonService.SendOOR:output_type -> waverpc.SendOORResponse - 13, // 134: waverpc.DaemonService.OnboardTaprootAsset:output_type -> waverpc.OnboardTaprootAssetResponse - 58, // 135: waverpc.DaemonService.PrepareOOR:output_type -> waverpc.PrepareOORResponse - 60, // 136: waverpc.DaemonService.SignOORCustomInput:output_type -> waverpc.SignOORCustomInputResponse - 62, // 137: waverpc.DaemonService.SignVTXOForfeit:output_type -> waverpc.SignVTXOForfeitResponse - 66, // 138: waverpc.DaemonService.RefreshVTXOs:output_type -> waverpc.RefreshVTXOsResponse - 72, // 139: waverpc.DaemonService.RefreshCustomVTXOs:output_type -> waverpc.RefreshCustomVTXOsResponse - 75, // 140: waverpc.DaemonService.ListPendingForfeitParticipantSignatureRequests:output_type -> waverpc.ListPendingForfeitParticipantSignatureRequestsResponse - 78, // 141: waverpc.DaemonService.SubmitForfeitParticipantSignatures:output_type -> waverpc.SubmitForfeitParticipantSignaturesResponse - 81, // 142: waverpc.DaemonService.LeaveVTXOs:output_type -> waverpc.LeaveVTXOsResponse - 83, // 143: waverpc.DaemonService.SendOnChain:output_type -> waverpc.SendOnChainResponse - 85, // 144: waverpc.DaemonService.Board:output_type -> waverpc.BoardResponse - 87, // 145: waverpc.DaemonService.JoinNextRound:output_type -> waverpc.JoinNextRoundResponse - 90, // 146: waverpc.DaemonService.SweepBoardingUTXOs:output_type -> waverpc.SweepBoardingUTXOsResponse - 94, // 147: waverpc.DaemonService.ListBoardingSweeps:output_type -> waverpc.ListBoardingSweepsResponse - 100, // 148: waverpc.DaemonService.ListRounds:output_type -> waverpc.ListRoundsResponse - 99, // 149: waverpc.DaemonService.GetRound:output_type -> waverpc.GetRoundResponse - 102, // 150: waverpc.DaemonService.WatchRounds:output_type -> waverpc.WatchRoundsResponse - 105, // 151: waverpc.DaemonService.ListOORSessions:output_type -> waverpc.ListOORSessionsResponse - 107, // 152: waverpc.DaemonService.GetOORSession:output_type -> waverpc.GetOORSessionResponse - 109, // 153: waverpc.DaemonService.EstimateFee:output_type -> waverpc.EstimateFeeResponse - 112, // 154: waverpc.DaemonService.GetFeeHistory:output_type -> waverpc.GetFeeHistoryResponse - 115, // 155: waverpc.DaemonService.ListTransactions:output_type -> waverpc.ListTransactionsResponse - 117, // 156: waverpc.DaemonService.Unroll:output_type -> waverpc.UnrollResponse - 122, // 157: waverpc.DaemonService.GetUnrollStatus:output_type -> waverpc.GetUnrollStatusResponse - 124, // 158: waverpc.DaemonService.ArmVHTLCRecovery:output_type -> waverpc.ArmVHTLCRecoveryResponse - 126, // 159: waverpc.DaemonService.EscalateVHTLCRecovery:output_type -> waverpc.EscalateVHTLCRecoveryResponse - 128, // 160: waverpc.DaemonService.CancelVHTLCRecovery:output_type -> waverpc.CancelVHTLCRecoveryResponse - 130, // 161: waverpc.DaemonService.GetVHTLCRecoveryStatus:output_type -> waverpc.GetVHTLCRecoveryStatusResponse - 132, // 162: waverpc.DaemonService.ListVHTLCRecoveries:output_type -> waverpc.ListVHTLCRecoveriesResponse - 117, // [117:163] is the sub-list for method output_type - 71, // [71:117] is the sub-list for method input_type - 71, // [71:71] is the sub-list for extension type_name - 71, // [71:71] is the sub-list for extension extendee - 0, // [0:71] is the sub-list for field type_name + 28, // 6: waverpc.VTXO.settlement:type_name -> waverpc.VTXOSettlement + 27, // 7: waverpc.VTXO.taproot_asset:type_name -> waverpc.VTXOTaprootAsset + 2, // 8: waverpc.ListVTXOsRequest.status_filter:type_name -> waverpc.VTXOStatus + 26, // 9: waverpc.ListVTXOsResponse.vtxos:type_name -> waverpc.VTXO + 2, // 10: waverpc.GetIndexedVTXOByPkScriptRequest.status_filter:type_name -> waverpc.VTXOStatus + 26, // 11: waverpc.GetIndexedVTXOByPkScriptResponse.vtxo:type_name -> waverpc.VTXO + 2, // 12: waverpc.GetVTXOExpiryInfoRequest.status_filter:type_name -> waverpc.VTXOStatus + 25, // 13: waverpc.GetVTXOExpiryInfoResponse.expiry_info:type_name -> waverpc.VTXOExpiryInfo + 26, // 14: waverpc.GetVTXOExpiryInfoResponse.vtxo:type_name -> waverpc.VTXO + 49, // 15: waverpc.SendVTXORequest.recipients:type_name -> waverpc.Output + 49, // 16: waverpc.SendOORRequest.recipients:type_name -> waverpc.Output + 54, // 17: waverpc.SendOORRequest.custom_inputs:type_name -> waverpc.CustomOORInput + 53, // 18: waverpc.SendOORRequest.taproot_asset:type_name -> waverpc.TaprootAssetOORIntent + 55, // 19: waverpc.CustomOORInput.external_signatures:type_name -> waverpc.TaprootScriptSignature + 49, // 20: waverpc.PrepareOORRequest.recipient:type_name -> waverpc.Output + 54, // 21: waverpc.PrepareOORRequest.custom_inputs:type_name -> waverpc.CustomOORInput + 58, // 22: waverpc.PrepareOORResponse.custom_inputs:type_name -> waverpc.PreparedOORCustomInput + 54, // 23: waverpc.SignOORCustomInputRequest.custom_input:type_name -> waverpc.CustomOORInput + 55, // 24: waverpc.SignOORCustomInputResponse.signature:type_name -> waverpc.TaprootScriptSignature + 4, // 25: waverpc.ForfeitSigningContext.signing_route:type_name -> waverpc.ForfeitSigningRoute + 65, // 26: waverpc.RefreshVTXOsRequest.outpoints:type_name -> waverpc.OutpointSelection + 68, // 27: waverpc.RefreshVTXOsResponse.fee_estimate:type_name -> waverpc.RefreshFeeEstimate + 69, // 28: waverpc.RefreshFeeEstimate.outpoints:type_name -> waverpc.OutpointFeeEstimate + 64, // 29: waverpc.CustomRefreshVTXOInput.forfeit_signing_context:type_name -> waverpc.ForfeitSigningContext + 70, // 30: waverpc.RefreshCustomVTXOsRequest.inputs:type_name -> waverpc.CustomRefreshVTXOInput + 71, // 31: waverpc.RefreshCustomVTXOsRequest.outputs:type_name -> waverpc.CustomRefreshVTXOOutput + 4, // 32: waverpc.PendingForfeitParticipantSignatureRequest.signing_route:type_name -> waverpc.ForfeitSigningRoute + 74, // 33: waverpc.ListPendingForfeitParticipantSignatureRequestsResponse.requests:type_name -> waverpc.PendingForfeitParticipantSignatureRequest + 77, // 34: waverpc.SubmitForfeitParticipantSignaturesRequest.signatures:type_name -> waverpc.ForfeitParticipantSignature + 65, // 35: waverpc.LeaveVTXOsRequest.outpoints:type_name -> waverpc.OutpointSelection + 80, // 36: waverpc.LeaveVTXOsRequest.default_destination:type_name -> waverpc.LeaveDestination + 135, // 37: waverpc.LeaveVTXOsRequest.destinations:type_name -> waverpc.LeaveVTXOsRequest.DestinationsEntry + 80, // 38: waverpc.SendOnChainRequest.destination:type_name -> waverpc.LeaveDestination + 90, // 39: waverpc.SweepBoardingUTXOsResponse.sweepable_outputs:type_name -> waverpc.BoardingSweepOutput + 93, // 40: waverpc.BoardingSweep.inputs:type_name -> waverpc.BoardingSweepInput + 94, // 41: waverpc.ListBoardingSweepsResponse.sweeps:type_name -> waverpc.BoardingSweep + 5, // 42: waverpc.RoundInfo.state:type_name -> waverpc.RoundState + 96, // 43: waverpc.RoundInfo.vtxos:type_name -> waverpc.RoundVTXOInfo + 5, // 44: waverpc.ListRoundsRequest.state_filter:type_name -> waverpc.RoundState + 97, // 45: waverpc.GetRoundResponse.round:type_name -> waverpc.RoundInfo + 97, // 46: waverpc.ListRoundsResponse.rounds:type_name -> waverpc.RoundInfo + 97, // 47: waverpc.WatchRoundsResponse.round:type_name -> waverpc.RoundInfo + 6, // 48: waverpc.OORSessionInfo.direction:type_name -> waverpc.OORSessionDirection + 7, // 49: waverpc.OORSessionInfo.status:type_name -> waverpc.OORSessionStatus + 6, // 50: waverpc.ListOORSessionsRequest.direction_filter:type_name -> waverpc.OORSessionDirection + 7, // 51: waverpc.ListOORSessionsRequest.status_filter:type_name -> waverpc.OORSessionStatus + 104, // 52: waverpc.ListOORSessionsResponse.sessions:type_name -> waverpc.OORSessionInfo + 104, // 53: waverpc.GetOORSessionResponse.session:type_name -> waverpc.OORSessionInfo + 112, // 54: waverpc.GetFeeHistoryResponse.entries:type_name -> waverpc.FeeHistoryEntry + 115, // 55: waverpc.ListTransactionsResponse.transactions:type_name -> waverpc.TransactionHistoryEntry + 8, // 56: waverpc.GetUnrollStatusResponse.status:type_name -> waverpc.UnrollJobStatus + 120, // 57: waverpc.GetUnrollStatusResponse.progress:type_name -> waverpc.UnrollProgress + 121, // 58: waverpc.GetUnrollStatusResponse.csv:type_name -> waverpc.UnrollCSV + 122, // 59: waverpc.GetUnrollStatusResponse.fees:type_name -> waverpc.UnrollFees + 9, // 60: waverpc.ArmVHTLCRecoveryRequest.direction:type_name -> waverpc.VHTLCRecoveryDirection + 10, // 61: waverpc.ArmVHTLCRecoveryRequest.action:type_name -> waverpc.VHTLCRecoveryAction + 134, // 62: waverpc.ArmVHTLCRecoveryResponse.status:type_name -> waverpc.VHTLCRecoveryStatus + 134, // 63: waverpc.EscalateVHTLCRecoveryResponse.status:type_name -> waverpc.VHTLCRecoveryStatus + 134, // 64: waverpc.CancelVHTLCRecoveryResponse.status:type_name -> waverpc.VHTLCRecoveryStatus + 134, // 65: waverpc.GetVHTLCRecoveryStatusResponse.status:type_name -> waverpc.VHTLCRecoveryStatus + 134, // 66: waverpc.ListVHTLCRecoveriesResponse.statuses:type_name -> waverpc.VHTLCRecoveryStatus + 9, // 67: waverpc.VHTLCRecoveryStatus.direction:type_name -> waverpc.VHTLCRecoveryDirection + 10, // 68: waverpc.VHTLCRecoveryStatus.action:type_name -> waverpc.VHTLCRecoveryAction + 11, // 69: waverpc.VHTLCRecoveryStatus.state:type_name -> waverpc.VHTLCRecoveryState + 8, // 70: waverpc.VHTLCRecoveryStatus.unroll_status:type_name -> waverpc.UnrollJobStatus + 80, // 71: waverpc.LeaveVTXOsRequest.DestinationsEntry.value:type_name -> waverpc.LeaveDestination + 14, // 72: waverpc.DaemonService.GetInfo:input_type -> waverpc.GetInfoRequest + 17, // 73: waverpc.DaemonService.GenSeed:input_type -> waverpc.GenSeedRequest + 19, // 74: waverpc.DaemonService.InitWallet:input_type -> waverpc.InitWalletRequest + 21, // 75: waverpc.DaemonService.UnlockWallet:input_type -> waverpc.UnlockWalletRequest + 23, // 76: waverpc.DaemonService.GetBalance:input_type -> waverpc.GetBalanceRequest + 29, // 77: waverpc.DaemonService.ListVTXOs:input_type -> waverpc.ListVTXOsRequest + 31, // 78: waverpc.DaemonService.NewAddress:input_type -> waverpc.NewAddressRequest + 33, // 79: waverpc.DaemonService.NewReceiveScript:input_type -> waverpc.NewReceiveScriptRequest + 35, // 80: waverpc.DaemonService.ReceiveAuthKey:input_type -> waverpc.ReceiveAuthKeyRequest + 37, // 81: waverpc.DaemonService.SignReceiveAuthMessage:input_type -> waverpc.SignReceiveAuthMessageRequest + 39, // 82: waverpc.DaemonService.SignReceiveAuthMessageCompact:input_type -> waverpc.SignReceiveAuthMessageCompactRequest + 41, // 83: waverpc.DaemonService.ReceiveAuthECDH:input_type -> waverpc.ReceiveAuthECDHRequest + 43, // 84: waverpc.DaemonService.GetIndexedVTXOByPkScript:input_type -> waverpc.GetIndexedVTXOByPkScriptRequest + 45, // 85: waverpc.DaemonService.GetVTXOExpiryInfo:input_type -> waverpc.GetVTXOExpiryInfoRequest + 47, // 86: waverpc.DaemonService.GetIndexedOORSessionByTxid:input_type -> waverpc.GetIndexedOORSessionByTxidRequest + 50, // 87: waverpc.DaemonService.SendVTXO:input_type -> waverpc.SendVTXORequest + 52, // 88: waverpc.DaemonService.SendOOR:input_type -> waverpc.SendOORRequest + 12, // 89: waverpc.DaemonService.OnboardTaprootAsset:input_type -> waverpc.OnboardTaprootAssetRequest + 57, // 90: waverpc.DaemonService.PrepareOOR:input_type -> waverpc.PrepareOORRequest + 60, // 91: waverpc.DaemonService.SignOORCustomInput:input_type -> waverpc.SignOORCustomInputRequest + 62, // 92: waverpc.DaemonService.SignVTXOForfeit:input_type -> waverpc.SignVTXOForfeitRequest + 66, // 93: waverpc.DaemonService.RefreshVTXOs:input_type -> waverpc.RefreshVTXOsRequest + 72, // 94: waverpc.DaemonService.RefreshCustomVTXOs:input_type -> waverpc.RefreshCustomVTXOsRequest + 75, // 95: waverpc.DaemonService.ListPendingForfeitParticipantSignatureRequests:input_type -> waverpc.ListPendingForfeitParticipantSignatureRequestsRequest + 78, // 96: waverpc.DaemonService.SubmitForfeitParticipantSignatures:input_type -> waverpc.SubmitForfeitParticipantSignaturesRequest + 81, // 97: waverpc.DaemonService.LeaveVTXOs:input_type -> waverpc.LeaveVTXOsRequest + 83, // 98: waverpc.DaemonService.SendOnChain:input_type -> waverpc.SendOnChainRequest + 85, // 99: waverpc.DaemonService.Board:input_type -> waverpc.BoardRequest + 87, // 100: waverpc.DaemonService.JoinNextRound:input_type -> waverpc.JoinNextRoundRequest + 89, // 101: waverpc.DaemonService.SweepBoardingUTXOs:input_type -> waverpc.SweepBoardingUTXOsRequest + 92, // 102: waverpc.DaemonService.ListBoardingSweeps:input_type -> waverpc.ListBoardingSweepsRequest + 98, // 103: waverpc.DaemonService.ListRounds:input_type -> waverpc.ListRoundsRequest + 99, // 104: waverpc.DaemonService.GetRound:input_type -> waverpc.GetRoundRequest + 102, // 105: waverpc.DaemonService.WatchRounds:input_type -> waverpc.WatchRoundsRequest + 105, // 106: waverpc.DaemonService.ListOORSessions:input_type -> waverpc.ListOORSessionsRequest + 107, // 107: waverpc.DaemonService.GetOORSession:input_type -> waverpc.GetOORSessionRequest + 109, // 108: waverpc.DaemonService.EstimateFee:input_type -> waverpc.EstimateFeeRequest + 111, // 109: waverpc.DaemonService.GetFeeHistory:input_type -> waverpc.GetFeeHistoryRequest + 114, // 110: waverpc.DaemonService.ListTransactions:input_type -> waverpc.ListTransactionsRequest + 117, // 111: waverpc.DaemonService.Unroll:input_type -> waverpc.UnrollRequest + 119, // 112: waverpc.DaemonService.GetUnrollStatus:input_type -> waverpc.GetUnrollStatusRequest + 124, // 113: waverpc.DaemonService.ArmVHTLCRecovery:input_type -> waverpc.ArmVHTLCRecoveryRequest + 126, // 114: waverpc.DaemonService.EscalateVHTLCRecovery:input_type -> waverpc.EscalateVHTLCRecoveryRequest + 128, // 115: waverpc.DaemonService.CancelVHTLCRecovery:input_type -> waverpc.CancelVHTLCRecoveryRequest + 130, // 116: waverpc.DaemonService.GetVHTLCRecoveryStatus:input_type -> waverpc.GetVHTLCRecoveryStatusRequest + 132, // 117: waverpc.DaemonService.ListVHTLCRecoveries:input_type -> waverpc.ListVHTLCRecoveriesRequest + 15, // 118: waverpc.DaemonService.GetInfo:output_type -> waverpc.GetInfoResponse + 18, // 119: waverpc.DaemonService.GenSeed:output_type -> waverpc.GenSeedResponse + 20, // 120: waverpc.DaemonService.InitWallet:output_type -> waverpc.InitWalletResponse + 22, // 121: waverpc.DaemonService.UnlockWallet:output_type -> waverpc.UnlockWalletResponse + 24, // 122: waverpc.DaemonService.GetBalance:output_type -> waverpc.GetBalanceResponse + 30, // 123: waverpc.DaemonService.ListVTXOs:output_type -> waverpc.ListVTXOsResponse + 32, // 124: waverpc.DaemonService.NewAddress:output_type -> waverpc.NewAddressResponse + 34, // 125: waverpc.DaemonService.NewReceiveScript:output_type -> waverpc.NewReceiveScriptResponse + 36, // 126: waverpc.DaemonService.ReceiveAuthKey:output_type -> waverpc.ReceiveAuthKeyResponse + 38, // 127: waverpc.DaemonService.SignReceiveAuthMessage:output_type -> waverpc.SignReceiveAuthMessageResponse + 40, // 128: waverpc.DaemonService.SignReceiveAuthMessageCompact:output_type -> waverpc.SignReceiveAuthMessageCompactResponse + 42, // 129: waverpc.DaemonService.ReceiveAuthECDH:output_type -> waverpc.ReceiveAuthECDHResponse + 44, // 130: waverpc.DaemonService.GetIndexedVTXOByPkScript:output_type -> waverpc.GetIndexedVTXOByPkScriptResponse + 46, // 131: waverpc.DaemonService.GetVTXOExpiryInfo:output_type -> waverpc.GetVTXOExpiryInfoResponse + 48, // 132: waverpc.DaemonService.GetIndexedOORSessionByTxid:output_type -> waverpc.GetIndexedOORSessionByTxidResponse + 51, // 133: waverpc.DaemonService.SendVTXO:output_type -> waverpc.SendVTXOResponse + 56, // 134: waverpc.DaemonService.SendOOR:output_type -> waverpc.SendOORResponse + 13, // 135: waverpc.DaemonService.OnboardTaprootAsset:output_type -> waverpc.OnboardTaprootAssetResponse + 59, // 136: waverpc.DaemonService.PrepareOOR:output_type -> waverpc.PrepareOORResponse + 61, // 137: waverpc.DaemonService.SignOORCustomInput:output_type -> waverpc.SignOORCustomInputResponse + 63, // 138: waverpc.DaemonService.SignVTXOForfeit:output_type -> waverpc.SignVTXOForfeitResponse + 67, // 139: waverpc.DaemonService.RefreshVTXOs:output_type -> waverpc.RefreshVTXOsResponse + 73, // 140: waverpc.DaemonService.RefreshCustomVTXOs:output_type -> waverpc.RefreshCustomVTXOsResponse + 76, // 141: waverpc.DaemonService.ListPendingForfeitParticipantSignatureRequests:output_type -> waverpc.ListPendingForfeitParticipantSignatureRequestsResponse + 79, // 142: waverpc.DaemonService.SubmitForfeitParticipantSignatures:output_type -> waverpc.SubmitForfeitParticipantSignaturesResponse + 82, // 143: waverpc.DaemonService.LeaveVTXOs:output_type -> waverpc.LeaveVTXOsResponse + 84, // 144: waverpc.DaemonService.SendOnChain:output_type -> waverpc.SendOnChainResponse + 86, // 145: waverpc.DaemonService.Board:output_type -> waverpc.BoardResponse + 88, // 146: waverpc.DaemonService.JoinNextRound:output_type -> waverpc.JoinNextRoundResponse + 91, // 147: waverpc.DaemonService.SweepBoardingUTXOs:output_type -> waverpc.SweepBoardingUTXOsResponse + 95, // 148: waverpc.DaemonService.ListBoardingSweeps:output_type -> waverpc.ListBoardingSweepsResponse + 101, // 149: waverpc.DaemonService.ListRounds:output_type -> waverpc.ListRoundsResponse + 100, // 150: waverpc.DaemonService.GetRound:output_type -> waverpc.GetRoundResponse + 103, // 151: waverpc.DaemonService.WatchRounds:output_type -> waverpc.WatchRoundsResponse + 106, // 152: waverpc.DaemonService.ListOORSessions:output_type -> waverpc.ListOORSessionsResponse + 108, // 153: waverpc.DaemonService.GetOORSession:output_type -> waverpc.GetOORSessionResponse + 110, // 154: waverpc.DaemonService.EstimateFee:output_type -> waverpc.EstimateFeeResponse + 113, // 155: waverpc.DaemonService.GetFeeHistory:output_type -> waverpc.GetFeeHistoryResponse + 116, // 156: waverpc.DaemonService.ListTransactions:output_type -> waverpc.ListTransactionsResponse + 118, // 157: waverpc.DaemonService.Unroll:output_type -> waverpc.UnrollResponse + 123, // 158: waverpc.DaemonService.GetUnrollStatus:output_type -> waverpc.GetUnrollStatusResponse + 125, // 159: waverpc.DaemonService.ArmVHTLCRecovery:output_type -> waverpc.ArmVHTLCRecoveryResponse + 127, // 160: waverpc.DaemonService.EscalateVHTLCRecovery:output_type -> waverpc.EscalateVHTLCRecoveryResponse + 129, // 161: waverpc.DaemonService.CancelVHTLCRecovery:output_type -> waverpc.CancelVHTLCRecoveryResponse + 131, // 162: waverpc.DaemonService.GetVHTLCRecoveryStatus:output_type -> waverpc.GetVHTLCRecoveryStatusResponse + 133, // 163: waverpc.DaemonService.ListVHTLCRecoveries:output_type -> waverpc.ListVHTLCRecoveriesResponse + 118, // [118:164] is the sub-list for method output_type + 72, // [72:118] is the sub-list for method input_type + 72, // [72:72] is the sub-list for extension type_name + 72, // [72:72] is the sub-list for extension extendee + 0, // [0:72] is the sub-list for field type_name } func init() { file_daemon_proto_init() } @@ -11749,29 +11831,29 @@ func file_daemon_proto_init() { if File_daemon_proto != nil { return } - file_daemon_proto_msgTypes[32].OneofWrappers = []any{ + file_daemon_proto_msgTypes[33].OneofWrappers = []any{ (*GetVTXOExpiryInfoRequest_Outpoint)(nil), (*GetVTXOExpiryInfoRequest_PkScript)(nil), } - file_daemon_proto_msgTypes[36].OneofWrappers = []any{ + file_daemon_proto_msgTypes[37].OneofWrappers = []any{ (*Output_Address)(nil), (*Output_Pubkey)(nil), (*Output_PolicyTemplate)(nil), } - file_daemon_proto_msgTypes[53].OneofWrappers = []any{ + file_daemon_proto_msgTypes[54].OneofWrappers = []any{ (*RefreshVTXOsRequest_Outpoints)(nil), (*RefreshVTXOsRequest_All)(nil), } - file_daemon_proto_msgTypes[55].OneofWrappers = []any{} - file_daemon_proto_msgTypes[67].OneofWrappers = []any{ + file_daemon_proto_msgTypes[56].OneofWrappers = []any{} + file_daemon_proto_msgTypes[68].OneofWrappers = []any{ (*LeaveDestination_Address)(nil), (*LeaveDestination_PkScript)(nil), } - file_daemon_proto_msgTypes[68].OneofWrappers = []any{ + file_daemon_proto_msgTypes[69].OneofWrappers = []any{ (*LeaveVTXOsRequest_Outpoints)(nil), (*LeaveVTXOsRequest_All)(nil), } - file_daemon_proto_msgTypes[70].OneofWrappers = []any{ + file_daemon_proto_msgTypes[71].OneofWrappers = []any{ (*SendOnChainRequest_AmountSat)(nil), (*SendOnChainRequest_SweepAll)(nil), } @@ -11781,7 +11863,7 @@ func file_daemon_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_proto_rawDesc), len(file_daemon_proto_rawDesc)), NumEnums: 12, - NumMessages: 123, + NumMessages: 124, NumExtensions: 0, NumServices: 1, }, diff --git a/waverpc/daemon.proto b/waverpc/daemon.proto index 76f69eb23..3e17bafb3 100644 --- a/waverpc/daemon.proto +++ b/waverpc/daemon.proto @@ -781,6 +781,23 @@ message VTXO { // only for FORFEITED VTXOs whose forfeit round is known, and unset // otherwise, so absence is explicit rather than a zero-value sentinel. VTXOSettlement settlement = 14; + + // taproot_asset is present when this VTXO carries a Taproot Asset. + // amount_sat above remains the separate Bitcoin carrier value. + VTXOTaprootAsset taproot_asset = 15; +} + +// VTXOTaprootAsset is SDK-neutral asset metadata attached to one VTXO. +message VTXOTaprootAsset { + // asset_ref is the opaque tap-sdk asset identity. + string asset_ref = 1; + + // amount is the number of Taproot Asset units carried by the VTXO. + uint64 amount = 2; + + // commitment_root is the 32-byte Taproot Asset commitment root composed + // beside the VTXO's semantic Ark policy. + bytes commitment_root = 3; } message VTXOSettlement {