lightninglabs / lightninglabs/taproot-assets
rpc: expose custom-anchor capabilities and a machine-readable API version via GetInfo
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 525
- Forks
- 150
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 31
Description
Problem
There is no runtime way for an RPC client to discover which custom-anchor features a given tapd backend supports, nor to obtain a stable, machine-readable API/capability version. The only version signal exposed to clients is a free-form human string.
This matters specifically for lightweight/custom-anchor integrations that don't run their own tapd and instead drive a remote/hosted daemon over gRPC (e.g. building a caller-owned BTC anchor, committing assets via CommitVirtualPsbts, signing externally, then PublishAndLogTransfer). Such a caller cannot compile against the backend's Go version constants, so it can't tell whether the backend supports a given field or RPC before invoking it. The available custom-anchor RPCs — FundVirtualPsbt, AnchorVirtualPsbts, CommitVirtualPsbts, PublishAndLogTransfer (taprpc/assetwalletrpc/assetwallet.proto:15, :34, :43, :52) — and their request options have grown over time; the only signal that a feature exists is either the presence of a proto field in the client's own generated stubs (which says nothing about the server) or trial-and-error against a live daemon. A concrete example is CommitVirtualPsbtsRequest.skip_funding (taprpc/assetwalletrpc/assetwallet.proto:354-358, honored at rpcserver/rpcserver.go:3058): an older backend silently ignores it, and there is no capability the client can query to know whether zero-fee / externally-funded anchoring is actually supported.
Current behaviour
GetInfo is declared at taprpc/taprootassets.proto:133 and returns GetInfoResponse (taprpc/taprootassets.proto:1715-1743). The response carries only: version (string), lnd_version, network, lnd_identity_pubkey, node_alias, block_height, block_hash, sync_to_chain. There is no capability list and no numeric/structured API version.
The server implementation at rpcserver/rpcserver.go:527-552 populates Version from r.cfg.Version. That value is wired in tapcfg/server.go as Version: tap.Version(), and Version() (version.go:159-161) returns a human-oriented string of the form "0.8.99-alpha commit=<...>" (assembled from AppMajor/AppMinor/AppPatch/AppStatus at version.go:41-51 plus the build Commit). A client that wants feature gating has to string-parse this and hard-code a semver→feature mapping — brittle across -alpha/-rc suffixes, forks, and LiT-embedded builds where the agent name is overridden (version.go:80-91).
There is no capabilities/feature-bit surface for RPC clients today. The FeatureBit machinery that does exist (tapchannel/aux_funding_controller.go:115-121, lndservices/feature_bit_verifier.go, rfq/manager.go) is for Lightning peer/channel negotiation over the wire protocol, not for describing an tapd node's RPC capabilities to a gRPC caller.
Test coverage confirms the gap: the GetInfo itest (itest/integration_test.go:154-173) only asserts the network field round-trips and that CLI and RPC responses match — nothing about versions or capabilities.
Proposed change
Extend discovery so a remote caller can gate custom-anchor flows without version-string parsing. Either extend GetInfoResponse or add a dedicated capabilities RPC on the TaprootAssets service:
- Add a structured, monotonic API/capability version to
GetInfoResponse(e.g.uint32 api_versionand/or splituint32 version_major/minor/patch) so clients have a stable integer to compare instead of parsingversion(taprpc/taprootassets.proto:1715). Populate it from theAppMajor/AppMinor/AppPatchconstants (version.go:41-48) inrpcserver.GetInfo(rpcserver/rpcserver.go:542-551). - Add an explicit, additive capability set — either a
repeated string capabilities/repeated Feature featuresfield onGetInfoResponse, or a newrpc GetCapabilities(...)on theTaprootAssetsservice (taprpc/taprootassets.proto:133neighborhood). Enumerate the custom-anchor capabilities the backend actually honors, e.g.custom_anchor_commit_psbts,custom_anchor_publish_and_log,commit_skip_funding,commit_custom_lock_id— so callers gate on named features rather than inferring them from a version. Feature names/bits should be defined once server-side and returned as data, so old clients ignore unknown entries and new clients degrade gracefully against old servers. - Add itest coverage extending
testGetInfo(itest/integration_test.go:154) to assert the API version and at least one custom-anchor capability are present.
Keeping this additive (new fields / new RPC) preserves backward compatibility with existing GetInfo consumers.
Context
Filed in support of lightninglabs/tap-sdk#158, which adds an advanced custom-anchor Taproot Assets transaction builder (caller owns the BTC anchor, commits assets via CommitVirtualPsbts, signs externally, then PublishAndLogTransfer). Because GetInfo exposes no machine-readable API version or capability set, the SDK currently pins a static, version-hardcoded compatibility profile and fails closed on any backend whose version it doesn't recognize — it cannot safely probe for features like skip_funding at runtime. A capabilities/API-version surface on GetInfo (or a dedicated RPC) would let the SDK negotiate features dynamically and stop rejecting otherwise-capable remote/hosted tapd backends.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the GetInfo declaration and GetInfoResponse in taprpc/taprootassets.proto, then read rpcserver/rpcserver.go and version.go to understand current population of version data. Review testGetInfo in itest/integration_test.go and the custom-anchor RPC definitions in taprpc/assetwalletrpc.proto. Done means clients can discover a stable API version and supported custom-anchor capabilities, with integration coverage confirming them.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100