Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/wasm-utxo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@
"./dist/cjs/js/wasm/wasm_utxo.js"
],
"scripts": {
"test": "npm run test:mocha && npm run test:wasm-pack && npm run test:imports",
"test": "npm run build:test && npm run test:mocha && npm run test:wasm-pack && npm run test:imports",
"build:test": "tsc --noEmit --project tsconfig.test.json",
"test:mocha": "mocha --recursive 'test/**/*.ts'",
"test:integrationLocalRpc": "mocha --config .mocharc.integrationLocalRpc.json --recursive 'test/integrationLocalRpc/**/*.test.ts'",
"test:integrationLocalRpc:generate": "tsx --experimental-wasm-modules test/integrationLocalRpc/generate/main.ts",
Expand All @@ -76,7 +77,7 @@
"build:ts-cjs": "tsc --project tsconfig.cjs.json",
"build:ts": "npm run build:ts-esm && npm run build:ts-cjs",
"build:package-json": "echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json",
"build": "npm run build:wasm && npm run build:ts && npm run build:package-json",
"build": "npm run build:wasm && npm run build:ts && npm run build:test && npm run build:package-json",
"check-fmt": "npm run lint:prettier && npm run lint:rustfmt",
"lint:prettier": "prettier --check .",
"lint:eslint": "eslint .",
Expand Down
2 changes: 1 addition & 1 deletion packages/wasm-utxo/test/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("isWasmUtxoError", function () {
before(function () {
try {
// Invalid pk_type triggers WasmUtxoError::new("Invalid descriptor type") → StringError
Descriptor.fromString("wsh(pk(abc))", "invalid_pk_type");
Descriptor.fromString("wsh(pk(abc))", "invalid_pk_type" as never);
} catch (e) {
error = e;
}
Expand Down
13 changes: 8 additions & 5 deletions packages/wasm-utxo/test/fixedScript/bchHydrateAndFinalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
import assert from "node:assert";
import * as utxolib from "@bitgo/utxo-lib";
import { AcidTest } from "../../js/testutils/AcidTest.js";
import { getKeyTriple } from "../../js/testutils/keys.js";
import { BitGoPsbt } from "../../js/fixedScriptWallet/BitGoPsbt.js";
import { ECPair } from "../../js/ecpair.js";
import type { HydrationUnspent } from "../../js/fixedScriptWallet/BitGoPsbt.js";

const [userXprv, , bitgoXprv] = getKeyTriple("default");

function buildHydrationUnspents(acid: AcidTest): HydrationUnspent[] {
const rpPubkey = acid.userXprv.publicKey;
const rpPubkey = userXprv.publicKey;
return acid.inputs.map((input, i) => {
if ("scriptType" in input && input.scriptType === "p2shP2pk") {
return { pubkey: rpPubkey, value: input.value };
Expand All @@ -39,7 +42,7 @@ describe("BCH p2shP2pk hydration (regression: 'Invalid hashType 0' / sig lost in
describe(`txFormat: ${txFormat}`, function () {
it("p2shP2pk sig preserved after fromNetworkFormat on half-signed tx", function () {
const acid = AcidTest.withConfig("bch", "halfsigned", txFormat);
const rpECPair = ECPair.fromPrivateKey(Buffer.from(acid.userXprv.privateKey));
const rpECPair = ECPair.fromPrivateKey(Buffer.from(userXprv.privateKey));
const rpIdx = acid.inputs.findIndex(
(i) => "scriptType" in i && i.scriptType === "p2shP2pk",
);
Expand All @@ -65,7 +68,7 @@ describe("BCH p2shP2pk hydration (regression: 'Invalid hashType 0' / sig lost in

it("p2shP2pk sig preserved after fromNetworkFormat on fully-signed tx", function () {
const acid = AcidTest.withConfig("bch", "fullsigned", txFormat);
const rpECPair = ECPair.fromPrivateKey(Buffer.from(acid.userXprv.privateKey));
const rpECPair = ECPair.fromPrivateKey(Buffer.from(userXprv.privateKey));
const rpIdx = acid.inputs.findIndex(
(i) => "scriptType" in i && i.scriptType === "p2shP2pk",
);
Expand All @@ -92,7 +95,7 @@ describe("BCH p2shP2pk hydration (regression: 'Invalid hashType 0' / sig lost in

it("finalization succeeds via utxolib after hydrate-and-cosign (wallet-platform scenario)", function () {
const acid = AcidTest.withConfig("bch", "halfsigned", txFormat);
const rpECPair = ECPair.fromPrivateKey(Buffer.from(acid.userXprv.privateKey));
const rpECPair = ECPair.fromPrivateKey(Buffer.from(userXprv.privateKey));
const rpIdx = acid.inputs.findIndex(
(i) => "scriptType" in i && i.scriptType === "p2shP2pk",
);
Expand All @@ -110,7 +113,7 @@ describe("BCH p2shP2pk hydration (regression: 'Invalid hashType 0' / sig lost in
);

// 3. HSM co-signs wallet inputs + p2shP2pk
hydratedPsbt.sign(acid.bitgoXprv);
hydratedPsbt.sign(bitgoXprv);
if (rpIdx >= 0) hydratedPsbt.signInput(rpIdx, rpECPair);

// 4. wallet-platform finalizes via utxolib
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,17 +185,14 @@ describe("parseTransactionWithWalletKeys", function () {
// isShielded is only meaningful for Zcash (Orchard/Ironwood); every other coin
// omits it since it has no concept of a shielded output.
if (networkName === "zec") {
assert.ok("isShielded" in output, `Output ${i} should expose isShielded for Zcash`);
assert.strictEqual(
output.isShielded,
false,
`Output ${i} isShielded should be false for a transparent Zcash output`,
);
} else {
assert.strictEqual(
output.isShielded,
undefined,
`Output ${i} isShielded should be absent for a non-Zcash coin`,
);
assert.ok(!("isShielded" in output), `Output ${i} should not expose isShielded`);
}
});

Expand Down
6 changes: 2 additions & 4 deletions packages/wasm-utxo/test/fixtures_thirdparty/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { describe } from "mocha";
import { getNetworkList, getNetworkName } from "../networks.js";
import { testFixtureArray, txValidTestFile, TxValidVector } from "./fixtures.js";
import { Transaction } from "../../js/index.js";
import { toCoinName } from "../../js/coinName.js";

describe("Third-Party Fixtures", function () {
getNetworkList().forEach((network) => {
Expand All @@ -14,15 +13,14 @@ describe("Third-Party Fixtures", function () {
const buffer = Buffer.from(txHex, "hex");

// Parse transaction using factory dispatch
const coin = toCoinName(getNetworkName(network));
const tx = Transaction.fromBytes(buffer, coin);
const tx = Transaction.fromBytes(buffer, network);

// Round-trip to verify serialization
const serialized = Buffer.from(tx.toBytes());
assert.deepEqual(
serialized,
buffer,
`Transaction round-trip failed for ${coin} vector ${i}`,
`Transaction round-trip failed for ${network} vector ${i}`,
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
type InputScriptType,
type OutputScriptType,
} from "../../js/fixedScriptWallet/index.js";
import { Descriptor, Transaction } from "../../js/index.js";
import { Descriptor } from "../../js/index.js";
import { createPsbt } from "../../js/descriptorWallet/psbt/createPsbt.js";
import { signWithKey } from "../../js/descriptorWallet/psbt/sign.js";
import type { CoinName } from "../../js/coinName.js";
Expand Down Expand Up @@ -61,7 +61,7 @@ function bytesToHex(bytes: Uint8Array): string {
async function nextMiningCoinbase(
rpc: RpcClient,
height: number,
): Promise<{ txid: string; vout: number; value: bigint; prevTxHex: string }> {
): Promise<{ txid: string; vout: number; value: bigint }> {
const hash = await rpc.getBlockHash(height);
const block = await rpc.getBlockVerbose(hash, 2);
const txs = block.rawtx ?? (block.tx as RpcTxVerbose[]);
Expand All @@ -73,7 +73,6 @@ async function nextMiningCoinbase(
txid: coinbase.txid,
vout: out.n,
value,
prevTxHex: coinbase.hex,
};
}

Expand All @@ -93,8 +92,6 @@ async function fundScriptFromMining(
);

const descriptor = Descriptor.fromString(PEARL_MINING_DESCRIPTOR, "definite");
const prevTx = Transaction.fromBytes(hexToBytes(coinbase.prevTxHex));

const psbt = createPsbt(
{ version: 2, locktime: 0 },
[
Expand All @@ -105,7 +102,6 @@ async function fundScriptFromMining(
script: hexToBytes(PEARL_MINING_TAPROOT_SCRIPT),
value: coinbase.value,
},
nonWitnessUtxo: prevTx.toBytes(),
descriptor,
},
],
Expand Down
Loading