Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add experimental silent payment transaction creation support - #220

Merged
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send
May 19, 2026
Merged

Add experimental silent payment transaction creation support#220
tvpeter merged 1 commit into
bitcoindevkit:masterfrom
nymius:feat/sp-psbt-send

Conversation

@nymius

@nymiusnymius commented Sep 10, 2025

Copy link
Copy Markdown
Contributor

Description

This PR adds experimental support for creating silent payment transactions through a new CreateSpTx command. The implementation integrates the bdk_sp crate to enable sending Bitcoin to silent payment addresses.

Key changes:

  • Adds bdk_sp dependency as an optional feature
  • Implements CreateSpTx command with support for silent payment recipients
  • Includes parser for silent payment address:amount pairs
  • Returns signed transactions ready for broadcast (not PSBTs due to silent payment derivation constraints)

Notes to the reviewers

  • This feature is marked as EXPERIMENTAL and includes warnings against mainnet use
  • The command returns signed transactions directly rather than PSBTs because silent payment script pubkey derivation cannot be performed securely in a trustless manner with standard PSBT workflows
  • RBF is disabled for silent payment transactions (sequence set to MAX)
  • The implementation handles both single key and extended key signers
  • Error handling uses temporary .expect() calls that should be addressed in future iterations

Changelog notice

Added: Experimental silent payment transaction creation via CreateSpTx command (feature-gated behind sp flag)

Checklists

All Submissions

New Features

* [ ] I've added tests for the new feature

  • I've added docs for the new feature

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on adding this feature @nymius,

I couldn't test because I don't know how to construct sp recipients. I will check the documentation on the library and will come back to test it. In the meantime, I have left some comments.
Thank you

Comment threadsrc/handlers.rs Outdated
Comment threadsrc/utils.rs Outdated
Comment threadsrc/commands.rs
Comment threadsrc/commands.rs
@nymius
nymius requested a review from tvpeterNovember 4, 2025 14:12

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for working on this feature @nymius

I left a few comments.

Pls remember to rebase too.

Comment threadsrc/error.rs
Comment threadsrc/handlers.rs Outdated
Comment threadsrc/handlers.rs
@tvpetertvpeter moved this to In Progress in BDK-CLIFeb 23, 2026

@sdmg15sdmg15 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tested ACK.

Script to use to reproduce

export NETWORK=regtest
export EXT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/0/*)'export INT_DESCRIPTOR='wpkh(tprv8ZgxMBicQKsPdMzWj9KHvoExKJDqfZFuT5D8o9XVZ3wfyUcnPNPJKncq5df8kpDWnMxoKbGrpS44VawHG17ZSwTkdhEtVRzSYXd14vDYXKw/1/*)'export DATABASE_TYPE="sqlite"export CLIENT_TYPE="rpc"export SERVER_URL="http://127.0.0.1:18443"export COOKIE="/home/user/.bitcoin/regtest/.cookie"export SP_RECIPIENT="sprt1qqdu4udd7wz7flf89m27teqzp8gxzvgpg3xudw89c0ce0f0pe0gwz6qkc4d7dg587w9rkaa0cj8rf3c28z0g45tgn0t7fzkk4s867w3eugga03ret"
raw_tx=$(cargo run -- wallet create_sp_tx --to-sp $SP_RECIPIENT:1000 | jq -r '.raw_tx'| tr -d '\n')
cargo run --features rpc -- wallet broadcast --tx $raw_tx
Image

Comment threadsrc/handlers.rs
let _resigned = wallet.sign(&mut psbt, SignOptions::default())?;

let raw_tx = psbt.extract_tx()?;
if cli_opts.pretty {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Here to actually make this "pretty", there's is this shorten function that can be used. I'm not though convinced if that's helpful for users wanting to copy the full raw tx maybe they should just not use the pretty format.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good point, I'm not sure about the use cases of the pretty flag, but I'm against shortening the transaction.

@nymius

Copy link
Copy Markdown
ContributorAuthor

I've addressed the pending comments:

  • Checked the finalization status of the PSBT after the signing phase before silent payment output derivation.
  • Implemented logic to handle the drain to silent payment case.

I've also:

  • Changed the feature flag sp to silent-payments for more clarity.
  • Squashed all commits into a single one.

@codecov

codecovBot commented Mar 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.55866% with 178 lines in your changes missing coverage. Please review.
✅ Project coverage is 10.22%. Comparing base (07fd32f) to head (c579854).
⚠️ Report is 7 commits behind head on master.

Files with missing linesPatch %Lines
src/handlers.rs0.61%162 Missing ⚠️
src/utils.rs0.00%16 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #220 +/- ##
==========================================
- Coverage 11.13% 10.22% -0.91% 
==========================================
Files 8 8 Lines 2488 2709 +221 ==========================================
Hits 277 277 - Misses 2211 2432 +221 
FlagCoverage Δ
rust10.22% <0.55%> (-0.91%)⬇️

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.

@nymius
nymiusforce-pushed the feat/sp-psbt-send branch 2 times, most recently from d297c8e to beaca7eCompareMarch 19, 2026 22:25
@notmandatorynotmandatory moved this from In Progress to Ready to Review in BDK-CLIMar 24, 2026
@sdmg15

Copy link
Copy Markdown
Contributor

reACK 516af1b

Comment threadsrc/commands.rs Outdated
Comment threadsrc/commands.rs Outdated

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK 516af1b

Well done @nymius, I have left a few nits for you.

Also, my final thoughts:
i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?
i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

@tvpetertvpeter added this to the CLI 4.0.0 milestone May 6, 2026
@tvpetertvpeter moved this from Ready to Review to In Progress in BDK-CLIMay 6, 2026
- Adds CreateSpTx command to create transactions with silent payment
outputs: this command creates signed transactions directly rather than
PSBTs due to current limitations in secure shared derivation.
It supports mixed recipients: regular addresses + silent payments.
It DOES NOT support RBF for the created transactions.
It generates signed transactions ready for broadcasting.
- Adds SilentPaymentCode command to create silent payment codes from
public keys and network: the silent payment code generated is
independent from any of the other stateful features of bdk-cli.
This command is mainly intended for experimental use, do not lock any
funds to the generated code if you don't know what you are doing and
don't have the keys matching the public keys used.
- Adds bdk_sp dependency with "silent-payments" feature flag.
- Adds silent payment recipient parsing utility.
- Add README section for new silent payment commands.
Note: This is experimental functionality for testing only, not
recommended for mainnet use.
Signed-off-by: nymius <155548262+nymius@users.noreply.github.com>
@nymius
nymiusforce-pushed the feat/sp-psbt-send branch from 516af1b to c579854CompareMay 11, 2026 13:58
@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

i) Since createtx and createsptx are almost similar, it would be great to merge createsptx into the existing createtx to improve the UX for users, but allow the fn to detect an SP address and handle it internally. This can be in another PR.

The idea of keeping them separated is that is easier to remove this command and replace it by a more mature silent payment sending command later. But we can work the details in another Issue/PR.

@tvpeter

Copy link
Copy Markdown
Collaborator

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

@nymius

Copy link
Copy Markdown
ContributorAuthor

Also, my final thoughts: i) With the current implementation, it is possible to send multiple outputs to the same SP code in the same tx. Can you consider checking for this?

I'm not sure I follow you here. The current implementation works with multiple SP codes or with a single one repeated multiple times. Do you mean if I have tested explicitly with bdk-cli? I can check it again.

The latter is what I am referring to; a single user can send more than one output to the same SP code e.g

... create_sp_tx --to-sp tsp1q...mh:5000 --to-sp tsp1q...mh:3000

I don't know whether this is considered key reuse. That is why I called your attention to check if it is acceptable.

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts. Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

@tvpeter

Copy link
Copy Markdown
Collaborator

That's one of the features from silent payments, you can reuse the same silent payment code in the transaction and you're going to get two different output scripts.

Alright then, that's fine.

Have you checked the outputs of the transactions? The one corresponding to the 5000 amount did look similar to the one sending 3000 sats?

I did not run it now; I ran it during my last test. I will inspect the output after I test shortly.

@tvpetertvpeter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

tACK c579854

Thank you for adding this feature @nymius.

I have now confirmed that it indeed produced different outputs.

Image

tvpeter

This comment was marked as duplicate.

@tvpeter
tvpeter merged commit 4a8e3ce into bitcoindevkit:masterMay 19, 2026
7 of 9 checks passed
@github-project-automationgithub-project-automationBot moved this from In Progress to Done in BDK-CLIMay 19, 2026
@tvpetertvpeter mentioned this pull request Jul 20, 2026
14 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants

@nymius@sdmg15@tvpeter@notmandatory