Skip to content

Add method to prove asset ownership#75

Open
berserker-systems wants to merge 3 commits into
RGB-Tools:masterfrom
deedsats:s/ownership
Open

Add method to prove asset ownership#75
berserker-systems wants to merge 3 commits into
RGB-Tools:masterfrom
deedsats:s/ownership

Conversation

@berserker-systems
Copy link
Copy Markdown

This method adds a way to prove the ownership of an asset. We need it to allow access to a service related to an asset.
If there is anything to improve, please let me know. The message is there to prevent signature-reuse.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

❌ Patch coverage is 93.02326% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.17%. Comparing base (5c62632) to head (fc10e94).

Files with missing lines Patch % Lines
src/wallet/singlesig.rs 92.94% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #75      +/-   ##
==========================================
- Coverage   95.19%   95.17%   -0.02%     
==========================================
  Files          23       23              
  Lines       11628    11713      +85     
==========================================
+ Hits        11069    11148      +79     
- Misses        559      565       +6     
Flag Coverage Δ
rust 95.17% <93.02%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zoedberg
Copy link
Copy Markdown
Member

The code has several issues, both on implementation, like usage of unwrap and missing logic to handle SegwitV0 wallets (recently added) and on logic, like missing support for assets allocated on blinded UTXOs.

But before discussing these issues I would like to understand if this method is actually needed. From what I see, everything can already be done with what rgb-lib provides, just call list_unspents to get the list of outpoints where the assets are, select the outpoint for which you want to prove ownership and then use whatever bitcoin library and language you want to sign this information.

@berserker-systems
Copy link
Copy Markdown
Author

@zoedberg
I agree with your observations. SegwitV0 needs to be added and to support blinded UTXOs the interface needs to change.

everything can already be done with what rgb-lib provides

The caller would need to duplicate the BDK wallet from the same descriptors, correct BIP-32 tree, witness version, keychain index, network-aware seed derivation. I'd rather not push that duplication onto callers.

More importantly, signing an outpoint isn't a free operation outside the library. BDK's derivation_of_spk only knows about indices it has indexed, so the duplicated wallet has to be synced against a chain source first (or the caller has to manually reveal addresses up to the right index) before the scriptPubKey -> (keychain, index) lookup works. Otherwise it returns None and the only way to recover the index is brute-forcing the child range until a derivation matches. rgb-lib already has a synced wallet with this state populated, so doing it inside is essentially free. Doing it outside means a full sync just to sign a message.

@zoedberg
Copy link
Copy Markdown
Member

BDK has a way to sync a single SPK, I think you could use that to avoid syncing a lot of unnecessary SPKs. With that you can do this operation outside rgb-lib without a noticeable overhead.

@berserker-systems
Copy link
Copy Markdown
Author

Single-SPK sync helps with chain sync, but the bottleneck is the lookup itself.

Given an outpoint from list_unspents, the caller doesn't know the (keychain, derivation_index) pair. To find it they have to derive children 0..N on the colored keychain, apply the tap-tweak (or not, depending on witness version), and compare each derived SPK against the outpoint's scriptPubKey until one matches. Single-SPK sync doesn't shortcut that, it's a derivation problem, not a network one.

The state that does shortcut it is BDK's reverse SPK -> (keychain, index) map, which only contains entries for already-revealed indices. rgb-lib's wallet has this populated as part of normal operation; an external caller starting from a fresh duplicated wallet has to either rebuild it (= reveal/derive up to N) or brute-force on every signing.

Plus, to derive at all the caller needs the descriptors and the witness version, wallet-internal conventions they'd have to read out of SinglesigKeys and apply correctly.

And there's the README:

This library is intended to exclusively handle all UTXOs for the wallet. Using the same mnemonic phrase on any other device, including with this same library, can lead to serious issues and ultimately to RGB asset loss.

I realise the strict reading of that is about operating on UTXOs from a second wallet, not read-only key derivation, so signing without broadcasting is technically safe. But it's still using the mnemonic somewhere other than rgb-lib, and I'd really rather not push callers toward that pattern, even for "harmless" signing operations, it's the kind of thing that drifts over time.

@zoedberg
Copy link
Copy Markdown
Member

What if we add the keychain and derivation index information to the unspent list?

@berserker-systems
Copy link
Copy Markdown
Author

@zoedberg
Adding keychain and derivation index to the unspent list would solve the reverse lookup problem, so I agree that it would make external signing more practical.

To better understand the preferred API boundary: what is the main reason you would not want rgb-lib itself to provide a controlled signing/proof method for wallet-owned UTXOs? Is the concern mostly about keeping rgb-lib’s API surface and maintenance burden minimal, avoiding responsibility for generic Bitcoin signing operations, or something else?

From my perspective, proving ownership of an RGB asset feels like something that naturally belongs in an RGB library, especially if rgb-lib already owns the wallet state and key-derivation context needed to do it safely and consistently. I may be biased here since this is my use case, but that is why I initially expected this functionality to fit within rgb-lib. That said, I am open to changing the API/interface if there is a better shape for this functionality or if a more general signing/proof abstraction would fit the library better.

@nicbus
Copy link
Copy Markdown
Member

nicbus commented Apr 30, 2026

The main concern is keeping the rgb-lib's public APIs clear and maintainable.

Adding a new API to provide functionality for a specific use case is outside the scope of the project, which aims to provide an abstraction over RGB primitives that is as simple as possible while retaining the needed flexibility. Adding info to an existing API which enables more use cases fits with the goals and doesn't impact maintenance much.

As for proving ownership of UTXOs (not RGB assets specifically), it doesn't look like something that adds value to rgb-lib, as for all current intents and purposes, ownership is already proven when spending and there are no cases where proving control over a UTXO seems useful on its own.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants