Skip to content

added tweak calculation & incoming UTXO detection#21

Merged
Overtorment merged 5 commits intomasterfrom
add-tweak-calculation
Sep 20, 2025
Merged

added tweak calculation & incoming UTXO detection#21
Overtorment merged 5 commits intomasterfrom
add-tweak-calculation

Conversation

@Overtorment
Copy link
Copy Markdown
Member

No description provided.

@Overtorment Overtorment requested a review from junderw March 11, 2025 13:17

// important, need the locking script from previous transaction, and we put it in place of unlocking
// script so the util that parses pubkeys can find the pubkey
tx.ins[0].script = txPrevout0.outs[0].script;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@junderw a lil guidance please? for this case to get pubkeys from inputs i have to assist it and provide locking script (input is p2tr). but for other testcases i can extract pubkeys from raw tx directly (inputs are p2wpkh). how can i tell by parsing txhex with bitcoinjs if i need to assist it and get prevout tx..?

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.

You can look at the witness and see if it matches a known P2TR pattern.

The only 3 types that have witness are P2WPKH, P2WSH, and P2TR.

ONLY P2TR will have pubkey info in the previous output's script... so you need to figure out if the witness is the witness of a P2WSH, a P2WPKH, or P2TR.

You could try using the payments API and running the input script and input witness through a P2WPKH payment then a P2WSH payment and if both fail assume it's P2TR and needs extra data.

Comment thread src/index.ts Outdated
Comment thread src/index.ts Outdated

static sumPubKeys(pubkeys: Uint8Array[], compressed: boolean = true): Uint8Array | null {
if (pubkeys.length === 0) return null;
if (pubkeys.length === 1) return concatUint8Arrays([new Uint8Array([2]), pubkeys[0]]); // not sure about this `2`
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@junderw i had to add leading 02 here, i guess it has smth to do with compressed pubkeys..? just want to make sure im not missing anything (my computations now match other implementation)

@Overtorment Overtorment changed the title added tweak calculation added tweak calculation & incoming UTXO detection May 7, 2025
@macgyver13
Copy link
Copy Markdown

Looks like you are on the right path to detecting UTXOs when provided with tweaks and able to derive a tweak from transaction inputs. I am not able to follow how tx prev outs script is being handled in the code base. I see a reference to setting it up in silent-payments.test but I think this will be the essence of one of the key challenges in receive wallet scanning.
To make any meaningful recommendations we should probably discuss the direction you intend to take with incorporating Silent Payments receiving in BlueWallet. Both of the options below are valid but have various tradeoffs:

  1. Leverage external tweak services to fetch tweaks and perform scriptPubKey matching on every qualifying transaction. I would read the Indexing Server Spec Proposal to get an idea of more options with this approach.
    • Additionally Dana Wallet has a complete implementation which uses tweaks and filters from blindbit-oracle to find relevant blocks / transactions to scan for silent payments.
    • A simplified example of using server provided tweaks can be found here.
  2. Download and scan each block / transaction for silent payments (looks like the path you are currently taking).
    Would also be worth reviewing if / how you might incorporate "labels" for silent payment addresses in BlueWallet. I can share some more considerations when you are ready to tackle this topic.

@Overtorment Overtorment marked this pull request as ready for review September 20, 2025 20:13
@Overtorment Overtorment merged commit fe84bac into master Sep 20, 2025
2 checks passed
@Overtorment Overtorment deleted the add-tweak-calculation branch September 20, 2025 20:13
Comment thread src/index.ts

ret.push(u);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: UTXO Detection and Key Generation Errors

In detectOurUtxos, the vout variable isn't incremented when iterating tx.outs, causing all detected UTXOs to incorrectly show vout: 0. Separately, the null check for the d variable (from ecc.privateAdd) is placed after d is already used to create an ECPair and WIF. This means if d is falsy, an error will occur before the check can catch it.

Fix in Cursor Fix in Web

Comment thread src/index.ts
if (result.length === 32) {
// its x-only...?
return concatUint8Arrays([new Uint8Array([2]), result]); // not sure about this `2`
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Incorrect Public Key Conversion

The sumPubKeys method incorrectly assumes an even y-coordinate when converting 32-byte x-only public keys to compressed format, always prepending 0x02. The correct prefix (0x02 or 0x03) depends on the actual y-coordinate parity, which isn't determined. This can lead to invalid public keys, as the comment "not sure about this 2" suggests.

Fix in Cursor Fix in Web

Comment thread src/index.ts
// looking for smallest outpoint:
const outpoints: Array<Uint8Array> = [];
for (const inn of tx.ins) {
const txidBuffer = inn.hash;//.reverse();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Byte Order Mismatch in Tweak Calculation

The computeTweakForTx method uses txids without reversing them, unlike _outpointsHash which explicitly reverses the txid buffer for outpoint hash calculation. This byte order inconsistency can lead to incorrect tweak computations and potential incompatibility with the BIP-352 specification.

Fix in Cursor Fix in Web

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants