Skip to content

Refactor/sp address use raw bytes#137

Open
Sosthene00 wants to merge 4 commits into
masterfrom
refactor/sp_address_use_raw_bytes
Open

Refactor/sp address use raw bytes#137
Sosthene00 wants to merge 4 commits into
masterfrom
refactor/sp_address_use_raw_bytes

Conversation

@Sosthene00

Copy link
Copy Markdown
Collaborator

Acknowledging that we often can't use SilentPaymentAddress type because we don't have the network, or we can have it but it's irrelevant, especially in psbt context, we need a type that only contains version, scan key and spend key. We also need to do back and forth with a bytes array representation of those data.

Instead of stripping the existing type of network, which would break all existing code, we propose to define another, simpler type, SilentPaymentAddressRaw, that is basically a very thin wrapper around a [u8; 67], but also offers type guarantees and more readability.

First place we would use that type is generate_recipient_pubkeys

@Sosthene00 Sosthene00 force-pushed the refactor/sp_address_use_raw_bytes branch 3 times, most recently from 53e3038 to 8cfa0a5 Compare June 23, 2026 13:14
@sdmg15

sdmg15 commented Jun 28, 2026

Copy link
Copy Markdown

Hello @Sosthene00
I wanted to take a look and help test/review. and noticed that the changes implemented here are also present in PR#143, so can you please enlighten me what will be the best way to help review/tests. Thanks

@Sosthene00

Copy link
Copy Markdown
Collaborator Author

Hi @sdmg15 and thanks for reaching out!

#143 was a bit big and hard to review so we splitted it in smaller PRs, that's why you will find that changes in this commit and some others are redundant with #143

I will close it now to prevent further confusion.

Regarding the changes made in that PR specifically, while it can be reviewed and tested in isolation (that was the whole point of splitting everything in smaller PRs in the first place), it has more sense considered with #138 #140 #141 #142

I'm not quite done moving every changes I made for psbts on that branch, so more PRs (1 or 2) are coming, I'll try to do that this week so that you can have the whole picture.

/// * Edge cases are hit during elliptic curve computation (extremely unlikely).
pub fn generate_recipient_pubkeys(
recipients: Vec<SilentPaymentAddress>,
recipients: Vec<SilentPaymentAddressRaw>,

@cygnet3 cygnet3 Jul 2, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Maybe instead of having recipients: Vec<SilentPaymentAddressRaw>, take recipients: impl Into<Vec<SilentPaymentAddressRaw>>, then we implement From<SilentPaymentAddress> for SilentPaymentAddressRaw to convert them automatically (which can be done in this direction). Then this function can take both Vec<SilentPaymentAddress> and Vec<SilentPaymentAddressRaw>.

Then we also don't need the from_byte_array and to_byte_array functions.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

That's elegant, but maybe a bit overkill here, since in practice generate_recipient_pubkeys is used inside higher level methods and will arguably mostly be used this way by downstream consumers of the lib. What I mean is that it's mostly about moving a simple conversion that happens in some place of our code higher in the stack.

Comment thread silentpayments/src/utils/common.rs Outdated
.expect("We did the same check than SilentPaymentAddress")
}

pub fn get_scan_pubkey(&self) -> PublicKey {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

If we're going to implement these high-level accessor functions then I think we might as well just define SilentPaymentAddressRaw as {version: SpVersion, scan_pubkey: PublicKey, m_pubkey: PublicKey }.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't know, the point of that type was to be a very thin wrapper around a bytes array, since it turned out it was easier and faster to work with for some methods. The PublicKey accessors make sense as a convenience, but the point is the other methods that let us read slice of raw bytes

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Since we're actively interpreting the contents of the byte array (reading both P_scan and P_m in generate_recipient_pubkeys), I don't think the 'thin wrapper' approach makes sense after all.

The only difference in how we use SilentPaymentAddress vs SilentPaymentAddressRaw is that the former contains knowledge of the intended network. That's useful in 2 cases:

  • when parsing an address string, to check if the network of the parsed address is correct
  • displaying the address, which requires the network type

Both of those cases are user/UI-facing. So I think the more sensible approach is to make the SilentPaymentAddress be the 'thin' struct for display/input parsing purposes, and make SilentPaymentAddressRaw be the 'main' struct for all the sp logic. What do you think of that approach?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I gave it a quick shot, that's pretty straightforward and it works, not sure of the implication, probably not much difference beside it being slightly more readable so that's still a win I guess. I gotta go will push a new version asap

Comment thread silentpayments/src/utils/common.rs Outdated
Sosthene00 and others added 4 commits July 2, 2026 23:46
…e address methods

Extract network-agnostic address data into a new SilentPaymentAddressRaw type.
Rename get_scan_key/get_spend_key/get_network/get_version to scan_key/spend_key/network/version,
and change version() to return SpVersion instead of u8. Add byte serialization helpers,
new_v0/from_raw constructors, and From conversions between the two types.

Co-authored-by: Cursor <cursoragent@cursor.com>
…::new

Co-authored-by: Cursor <cursoragent@cursor.com>
generate_recipient_pubkeys now accepts and returns SilentPaymentAddressRaw,
removing the network information from the type used in the actual ECC computation.

Co-authored-by: Cursor <cursoragent@cursor.com>
Mechanically replace get_scan_key/get_spend_key/get_network/get_version with
the renamed scan_key/spend_key/network/version across examples, tests, and
spdk-wallet. Also convert SilentPaymentAddress to SilentPaymentAddressRaw where
the sending API is called.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Sosthene00 Sosthene00 force-pushed the refactor/sp_address_use_raw_bytes branch from 8cfa0a5 to a482803 Compare July 2, 2026 21:47
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