Skip to content

Commit 0589ab8

Browse files
update fixtures
test(wasm-utxo): add psbt-format fixtures for all 7 coins Generate unsigned/halfsigned/fullsigned PSBT fixtures (with non_witness_utxo) for bitcoin, bitcoincash, bitcoingold, dash, dogecoin, ecash, and litecoin.
1 parent a7ad12a commit 0589ab8

50 files changed

Lines changed: 2569 additions & 6344 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/wasm-utxo/test/fixedScript/parseTransactionWithWalletKeys.ts

Lines changed: 247 additions & 235 deletions
Large diffs are not rendered by default.

packages/wasm-utxo/test/fixedScript/signAndVerifySignature.ts

Lines changed: 154 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -247,161 +247,161 @@ describe("verifySignature", function () {
247247
txFormats
248248
.filter((f) => f !== "psbt" || networkName !== "zcash")
249249
.forEach((txFormat) => {
250-
describe(`${networkName} ${txFormat}`, function () {
251-
let rootWalletKeys: RootWalletKeys;
252-
let replayProtectionKey: ECPair;
253-
let xprivs: RootWalletXprivs;
254-
let unsignedFixture: Fixture;
255-
let halfsignedFixture: Fixture;
256-
let fullsignedFixture: Fixture;
257-
258-
before(async function () {
259-
unsignedFixture = await loadPsbtFixture(networkName, "unsigned", txFormat);
260-
halfsignedFixture = await loadPsbtFixture(networkName, "halfsigned", txFormat);
261-
fullsignedFixture = await loadPsbtFixture(networkName, "fullsigned", txFormat);
262-
rootWalletKeys = loadWalletKeysFromFixture(fullsignedFixture);
263-
replayProtectionKey = loadReplayProtectionKeyFromFixture(fullsignedFixture);
264-
xprivs = loadXprivsFromFixture(fullsignedFixture);
265-
});
266-
267-
describe("unsigned PSBT", function () {
268-
it("should return false for unsigned inputs, then sign and verify", function () {
269-
runTestsForFixture(
270-
unsignedFixture,
271-
networkName,
272-
rootWalletKeys,
273-
replayProtectionKey,
274-
xprivs,
275-
"unsigned",
276-
);
277-
});
278-
});
279-
280-
describe("half-signed PSBT", function () {
281-
it("should return true for signed xpubs and false for unsigned, then sign and verify", function () {
282-
runTestsForFixture(
283-
halfsignedFixture,
284-
networkName,
285-
rootWalletKeys,
286-
replayProtectionKey,
287-
xprivs,
288-
"halfsigned",
289-
);
290-
});
291-
});
292-
293-
describe("fully signed PSBT", function () {
294-
it("should have 2 signatures (2-of-3 multisig)", function () {
295-
runTestsForFixture(
296-
fullsignedFixture,
297-
networkName,
298-
rootWalletKeys,
299-
replayProtectionKey,
300-
xprivs,
301-
"fullsigned",
302-
);
303-
});
304-
});
305-
306-
describe("error handling", function () {
307-
it("should throw error for out of bounds input index", function () {
308-
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
309-
assert.throws(
310-
() => {
311-
psbt.verifySignature(999, rootWalletKeys.userKey());
312-
},
313-
(error: Error) => {
314-
return error.message.includes("Input index 999 out of bounds");
315-
},
316-
"Should throw error for out of bounds input index",
317-
);
250+
describe(`${networkName} ${txFormat}`, function () {
251+
let rootWalletKeys: RootWalletKeys;
252+
let replayProtectionKey: ECPair;
253+
let xprivs: RootWalletXprivs;
254+
let unsignedFixture: Fixture;
255+
let halfsignedFixture: Fixture;
256+
let fullsignedFixture: Fixture;
257+
258+
before(async function () {
259+
unsignedFixture = await loadPsbtFixture(networkName, "unsigned", txFormat);
260+
halfsignedFixture = await loadPsbtFixture(networkName, "halfsigned", txFormat);
261+
fullsignedFixture = await loadPsbtFixture(networkName, "fullsigned", txFormat);
262+
rootWalletKeys = loadWalletKeysFromFixture(fullsignedFixture);
263+
replayProtectionKey = loadReplayProtectionKeyFromFixture(fullsignedFixture);
264+
xprivs = loadXprivsFromFixture(fullsignedFixture);
265+
});
266+
267+
describe("unsigned PSBT", function () {
268+
it("should return false for unsigned inputs, then sign and verify", function () {
269+
runTestsForFixture(
270+
unsignedFixture,
271+
networkName,
272+
rootWalletKeys,
273+
replayProtectionKey,
274+
xprivs,
275+
"unsigned",
276+
);
277+
});
278+
});
279+
280+
describe("half-signed PSBT", function () {
281+
it("should return true for signed xpubs and false for unsigned, then sign and verify", function () {
282+
runTestsForFixture(
283+
halfsignedFixture,
284+
networkName,
285+
rootWalletKeys,
286+
replayProtectionKey,
287+
xprivs,
288+
"halfsigned",
289+
);
290+
});
291+
});
292+
293+
describe("fully signed PSBT", function () {
294+
it("should have 2 signatures (2-of-3 multisig)", function () {
295+
runTestsForFixture(
296+
fullsignedFixture,
297+
networkName,
298+
rootWalletKeys,
299+
replayProtectionKey,
300+
xprivs,
301+
"fullsigned",
302+
);
303+
});
304+
});
305+
306+
describe("error handling", function () {
307+
it("should throw error for out of bounds input index", function () {
308+
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
309+
assert.throws(
310+
() => {
311+
psbt.verifySignature(999, rootWalletKeys.userKey());
312+
},
313+
(error: Error) => {
314+
return error.message.includes("Input index 999 out of bounds");
315+
},
316+
"Should throw error for out of bounds input index",
317+
);
318+
});
319+
320+
it("should throw error for invalid xpub", function () {
321+
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
322+
assert.throws(
323+
() => {
324+
psbt.verifySignature(0, "invalid-xpub");
325+
},
326+
(error: Error) => {
327+
return error.message.includes("Invalid");
328+
},
329+
"Should throw error for invalid xpub",
330+
);
331+
});
332+
333+
it("should return false for xpub not in derivation path", function () {
334+
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
335+
// Create a different xpub that's not in the wallet
336+
// Use a proper 32-byte seed (256 bits)
337+
const differentSeed = Buffer.alloc(32, 0xaa); // 32 bytes filled with 0xaa
338+
const differentKey = BIP32.fromSeed(differentSeed);
339+
const differentXpub = differentKey.neutered();
340+
341+
const result = psbt.verifySignature(0, differentXpub);
342+
assert.strictEqual(
343+
result,
344+
false,
345+
"Should return false for xpub not in PSBT derivation paths",
346+
);
347+
});
348+
349+
it("should verify signature with raw public key (Uint8Array)", function () {
350+
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
351+
// Find first wallet input (non-p2shP2pk) for xpub verification
352+
const walletInputIndex = fullsignedFixture.psbtInputs.findIndex(
353+
(input) => input.type !== "p2shP2pk",
354+
);
355+
assert.ok(walletInputIndex >= 0, "Should have a wallet input");
356+
357+
// Verify that xpub-based verification works
358+
const userKey = rootWalletKeys.userKey();
359+
const hasXpubSig = psbt.verifySignature(walletInputIndex, userKey);
360+
361+
// Use a random public key that's not in the PSBT to test the API works
362+
const randomSeed = Buffer.alloc(32, 0xcc);
363+
const randomKey = BIP32.fromSeed(randomSeed);
364+
const randomPubkey = randomKey.publicKey;
365+
366+
// This should return false (no signature for this key)
367+
const result = psbt.verifySignature(walletInputIndex, randomPubkey);
368+
assert.strictEqual(result, false, "Should return false for public key not in PSBT");
369+
370+
// Verify the xpub check still works (regression test)
371+
assert.strictEqual(hasXpubSig, true, "Should still verify with xpub");
372+
});
373+
374+
it("should return false for raw public key with no signature", function () {
375+
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
376+
// Create a random public key that's not in the PSBT
377+
const randomSeed = Buffer.alloc(32, 0xbb);
378+
const randomKey = BIP32.fromSeed(randomSeed);
379+
const randomPubkey = randomKey.publicKey;
380+
381+
const result = psbt.verifySignature(0, randomPubkey);
382+
assert.strictEqual(
383+
result,
384+
false,
385+
"Should return false for public key not in PSBT signatures",
386+
);
387+
});
388+
389+
it("should throw error for invalid key length", function () {
390+
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
391+
const invalidKey = Buffer.alloc(31); // Invalid length (should be 32 for private key or 33 for public key)
392+
393+
assert.throws(
394+
() => {
395+
psbt.verifySignature(0, invalidKey);
396+
},
397+
(error: Error) => {
398+
return error.message.includes("Invalid key length");
399+
},
400+
"Should throw error for invalid key length",
401+
);
402+
});
403+
});
318404
});
319-
320-
it("should throw error for invalid xpub", function () {
321-
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
322-
assert.throws(
323-
() => {
324-
psbt.verifySignature(0, "invalid-xpub");
325-
},
326-
(error: Error) => {
327-
return error.message.includes("Invalid");
328-
},
329-
"Should throw error for invalid xpub",
330-
);
331-
});
332-
333-
it("should return false for xpub not in derivation path", function () {
334-
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
335-
// Create a different xpub that's not in the wallet
336-
// Use a proper 32-byte seed (256 bits)
337-
const differentSeed = Buffer.alloc(32, 0xaa); // 32 bytes filled with 0xaa
338-
const differentKey = BIP32.fromSeed(differentSeed);
339-
const differentXpub = differentKey.neutered();
340-
341-
const result = psbt.verifySignature(0, differentXpub);
342-
assert.strictEqual(
343-
result,
344-
false,
345-
"Should return false for xpub not in PSBT derivation paths",
346-
);
347-
});
348-
349-
it("should verify signature with raw public key (Uint8Array)", function () {
350-
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
351-
// Find first wallet input (non-p2shP2pk) for xpub verification
352-
const walletInputIndex = fullsignedFixture.psbtInputs.findIndex(
353-
(input) => input.type !== "p2shP2pk",
354-
);
355-
assert.ok(walletInputIndex >= 0, "Should have a wallet input");
356-
357-
// Verify that xpub-based verification works
358-
const userKey = rootWalletKeys.userKey();
359-
const hasXpubSig = psbt.verifySignature(walletInputIndex, userKey);
360-
361-
// Use a random public key that's not in the PSBT to test the API works
362-
const randomSeed = Buffer.alloc(32, 0xcc);
363-
const randomKey = BIP32.fromSeed(randomSeed);
364-
const randomPubkey = randomKey.publicKey;
365-
366-
// This should return false (no signature for this key)
367-
const result = psbt.verifySignature(walletInputIndex, randomPubkey);
368-
assert.strictEqual(result, false, "Should return false for public key not in PSBT");
369-
370-
// Verify the xpub check still works (regression test)
371-
assert.strictEqual(hasXpubSig, true, "Should still verify with xpub");
372-
});
373-
374-
it("should return false for raw public key with no signature", function () {
375-
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
376-
// Create a random public key that's not in the PSBT
377-
const randomSeed = Buffer.alloc(32, 0xbb);
378-
const randomKey = BIP32.fromSeed(randomSeed);
379-
const randomPubkey = randomKey.publicKey;
380-
381-
const result = psbt.verifySignature(0, randomPubkey);
382-
assert.strictEqual(
383-
result,
384-
false,
385-
"Should return false for public key not in PSBT signatures",
386-
);
387-
});
388-
389-
it("should throw error for invalid key length", function () {
390-
const psbt = getBitGoPsbt(fullsignedFixture, networkName);
391-
const invalidKey = Buffer.alloc(31); // Invalid length (should be 32 for private key or 33 for public key)
392-
393-
assert.throws(
394-
() => {
395-
psbt.verifySignature(0, invalidKey);
396-
},
397-
(error: Error) => {
398-
return error.message.includes("Invalid key length");
399-
},
400-
"Should throw error for invalid key length",
401-
);
402-
});
403-
});
404-
});
405405
});
406406
});
407407
});

0 commit comments

Comments
 (0)