Skip to content

Commit

Permalink
fix: tests and legacy psbts should respect network for global xpubs
Browse files Browse the repository at this point in the history
  • Loading branch information
bucko13 committed May 3, 2024
1 parent 09e5a67 commit 698091f
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/light-plants-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@caravan/bitcoin": major
---

transaction parser was stripping out network information from global xpubs being added to psbt. global xpubs will now respect the network and include appropriate prefix
8 changes: 8 additions & 0 deletions packages/caravan-bitcoin/src/psbtv2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,14 @@ const BIP_174_VECTORS_VALID_PSBT = [
];

describe("PsbtV2", () => {
beforeAll(() => {
global.console.warn = jest.fn().mockImplementation(() => {});
global.console.error = jest.fn().mockImplementation(() => {});
});
afterAll(() => {
(global.console.warn as jest.Mock).mockRestore();
(global.console.error as jest.Mock).mockRestore();
});
test.each(BIP_370_VECTORS_INVALID_PSBT)(
"Throws with BIP0370 test vectors. $case",
(vect) => {
Expand Down
44 changes: 22 additions & 22 deletions packages/caravan-bitcoin/src/transactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ describe("transactions", () => {
const transaction = unsignedMultisigTransaction(
fixture.network,
fixture.inputs,
fixture.outputs
fixture.outputs,
);
if (fixture.psbt) {
const transactionFromPSBT = unsignedTransactionObjectFromPSBT(
unsignedMultisigPSBT(
fixture.network,
fixture.inputs,
fixture.outputs
)
fixture.outputs,
),
);
expect(transaction).toEqual(transactionFromPSBT);
}
Expand All @@ -72,18 +72,18 @@ describe("transactions", () => {
const reversedTXIDBuffer = transaction.ins[inputIndex].hash;
// Don't want to modify buffer in place so use Buffer.from
expect(
toHexString(Buffer.from(reversedTXIDBuffer).reverse())
toHexString(Buffer.from(reversedTXIDBuffer).reverse()),
).toEqual(input.txid);
});
fixture.outputs.forEach((output, outputIndex) => {
expect(transaction.outs[outputIndex].value).toEqual(
Number(output.amountSats)
Number(output.amountSats),
);
expect(
address.fromOutputScript(
transaction.outs[outputIndex].script,
networkData(fixture.network)
)
networkData(fixture.network),
),
).toEqual(output.address);
});
expect(transaction.toHex()).toEqual(fixture.hex);
Expand Down Expand Up @@ -126,7 +126,7 @@ describe("transactions", () => {
const psbt = unsignedMultisigPSBT(
fixture.network,
fixture.inputs,
fixture.outputs
fixture.outputs,
);
expect(fixture.psbt).toEqual(psbt.data.toBase64());
}
Expand All @@ -140,7 +140,7 @@ describe("transactions", () => {
fixture.network,
fixture.inputs,
fixture.outputs,
true
true,
);

expect(fixture.psbt).not.toEqual(psbt.data.toBase64());
Expand Down Expand Up @@ -182,15 +182,15 @@ describe("transactions", () => {
signedMultisigTransaction(
fixture.network,
fixture.inputs,
fixture.outputs
fixture.outputs,
);
}).toThrow(/at least one transaction signature/i);
expect(() => {
signedMultisigTransaction(
fixture.network,
fixture.inputs,
fixture.outputs,
[]
[],
);
}).toThrow(/at least one transaction signature/i);
});
Expand All @@ -201,15 +201,15 @@ describe("transactions", () => {
fixture.network,
fixture.inputs,
fixture.outputs,
[[]]
[[]],
);
}).toThrow(/insufficient input signatures/i);
expect(() => {
signedMultisigTransaction(
fixture.network,
fixture.inputs,
fixture.outputs,
[fixture.signature, []]
[fixture.signature, []],
);
}).toThrow(/insufficient input signatures/i);
});
Expand All @@ -220,7 +220,7 @@ describe("transactions", () => {
fixture.network,
fixture.inputs,
fixture.outputs,
[fixture.signature]
[fixture.signature],
);
}).toThrow(/insufficient signatures for input/i);
});
Expand All @@ -231,7 +231,7 @@ describe("transactions", () => {
fixture.network,
fixture.inputs,
fixture.outputs,
[fixture.signature, ["foo", "bar", "baz"]]
[fixture.signature, ["foo", "bar", "baz"]],
);
}).toThrow(/invalid signature for input/i);
});
Expand All @@ -242,7 +242,7 @@ describe("transactions", () => {
fixture.network,
fixture.inputs,
fixture.outputs,
[fixture.signature, fixture.signature]
[fixture.signature, fixture.signature],
);
}).toThrow(/duplicate signature for input/i);
});
Expand All @@ -253,7 +253,7 @@ describe("transactions", () => {
const multisig = generateMultisigFromHex(
Network.TESTNET,
P2SH,
redeemScriptHex
redeemScriptHex,
);

// This transaction has already been broadcast as
Expand Down Expand Up @@ -290,7 +290,7 @@ describe("transactions", () => {
Network.TESTNET,
inputs,
outputs,
[transactionSignature1, transactionSignature2]
[transactionSignature1, transactionSignature2],
);

expect(signedTransaction.toHex()).toEqual(signedTransactionHex);
Expand All @@ -302,7 +302,7 @@ describe("transactions", () => {
const multisig = generateMultisigFromHex(
Network.TESTNET,
P2SH_P2WSH,
witnessScriptHex
witnessScriptHex,
);

// This transaction has already been broadcast as
Expand Down Expand Up @@ -336,7 +336,7 @@ describe("transactions", () => {
Network.TESTNET,
inputs,
outputs,
[transactionSignature1, transactionSignature2]
[transactionSignature1, transactionSignature2],
);

expect(signedTransaction.toHex()).toEqual(signedTransactionHex);
Expand All @@ -348,7 +348,7 @@ describe("transactions", () => {
const multisig = generateMultisigFromHex(
Network.TESTNET,
P2WSH,
witnessScriptHex
witnessScriptHex,
);

// This transaction has already been broadcast as
Expand Down Expand Up @@ -383,7 +383,7 @@ describe("transactions", () => {
Network.TESTNET,
inputs,
outputs,
[transactionSignature1, transactionSignature2]
[transactionSignature1, transactionSignature2],
);

expect(signedTransaction.toHex()).toEqual(signedTransactionHex);
Expand Down
7 changes: 5 additions & 2 deletions packages/caravan-bitcoin/src/transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,15 @@ export function unsignedMultisigPSBT(
if (braidDetails && includeGlobalXpubs) {
const braid = Braid.fromData(JSON.parse(braidDetails));
braid.extendedPublicKeys.forEach((extendedPublicKeyData) => {
const extendedPublicKey = new ExtendedPublicKey(extendedPublicKeyData);
const extendedPublicKey = new ExtendedPublicKey({
...extendedPublicKeyData,
network,
});

const alreadyFound = globalExtendedPublicKeys.find(
(existingExtendedPublicKey: any) =>
existingExtendedPublicKey.toBase58() ===
extendedPublicKey.toBase58()
extendedPublicKey.toBase58(),
);

if (!alreadyFound) {
Expand Down
2 changes: 1 addition & 1 deletion packages/caravan-psbt/src/psbtv0/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ const psbtOutputFormatter = (output: PsbtOutput, network: Network) => {
const script = toOutputScript(output.address, networkData(network));
const outputData: any = {
...output,
// script: toOutputScript(output.address, networkData(network)),
script,
value: output.value,
};
Expand All @@ -124,6 +123,7 @@ export const addGlobalXpubs = (
) => {
const globalXpubs = multisigConfig.extendedPublicKeys.map(
({ xfp, bip32Path, xpub }) => {
console.log("xpub:", xpub);
return {
extendedPubkey: ExtendedPublicKey.fromBase58(xpub).encode(),
masterFingerprint: xfp ? Buffer.from(xfp, "hex") : Buffer.alloc(0),
Expand Down

0 comments on commit 698091f

Please sign in to comment.