diff --git a/packages/wasm-utxo/js/coinName.ts b/packages/wasm-utxo/js/coinName.ts index 7dd350a2..aae222bb 100644 --- a/packages/wasm-utxo/js/coinName.ts +++ b/packages/wasm-utxo/js/coinName.ts @@ -64,3 +64,54 @@ export function isTestnet(name: CoinName): boolean { export function isCoinName(v: string): v is CoinName { return (coinNames as readonly string[]).includes(v); } + +import type { UtxolibName } from "./utxolibCompat.js"; + +/** Convert a CoinName or UtxolibName to CoinName */ +export function toCoinName(name: CoinName | UtxolibName): CoinName { + switch (name) { + case "bitcoin": + return "btc"; + case "testnet": + return "tbtc"; + case "bitcoinTestnet4": + return "tbtc4"; + case "bitcoinPublicSignet": + return "tbtcsig"; + case "bitcoinBitGoSignet": + return "tbtcbgsig"; + case "bitcoincash": + return "bch"; + case "bitcoincashTestnet": + return "tbch"; + case "ecash": + return "bcha"; + case "ecashTest": + return "tbcha"; + case "bitcoingold": + return "btg"; + case "bitcoingoldTestnet": + return "tbtg"; + case "bitcoinsv": + return "bsv"; + case "bitcoinsvTestnet": + return "tbsv"; + case "dashTest": + return "tdash"; + case "dogecoin": + return "doge"; + case "dogecoinTest": + return "tdoge"; + case "litecoin": + return "ltc"; + case "litecoinTest": + return "tltc"; + case "zcash": + return "zec"; + case "zcashTest": + return "tzec"; + default: + // CoinName values pass through (including "dash" which is both CoinName and UtxolibName) + return name; + } +} diff --git a/packages/wasm-utxo/js/testutils/AcidTest.ts b/packages/wasm-utxo/js/testutils/AcidTest.ts index 19fb06e2..3d4b54a4 100644 --- a/packages/wasm-utxo/js/testutils/AcidTest.ts +++ b/packages/wasm-utxo/js/testutils/AcidTest.ts @@ -3,13 +3,14 @@ import { ZcashBitGoPsbt } from "../fixedScriptWallet/ZcashBitGoPsbt.js"; import { RootWalletKeys } from "../fixedScriptWallet/RootWalletKeys.js"; import { BIP32 } from "../bip32.js"; import { ECPair } from "../ecpair.js"; +import { Transaction } from "../transaction.js"; import { - assertChainCode, ChainCode, createOpReturnScript, inputScriptTypes, outputScript, outputScriptTypes, + p2shP2pkOutputScript, supportsScriptType, type InputScriptType, type OutputScriptType, @@ -91,6 +92,22 @@ type SuiteConfig = { // Re-export for convenience export { inputScriptTypes, outputScriptTypes }; +/** Map InputScriptType to the OutputScriptType used for chain code derivation */ +function inputScriptTypeToOutputScriptType(scriptType: InputScriptType): OutputScriptType { + switch (scriptType) { + case "p2sh": + case "p2shP2wsh": + case "p2wsh": + case "p2trLegacy": + return scriptType; + case "p2shP2pk": + return "p2sh"; + case "p2trMusig2ScriptPath": + case "p2trMusig2KeyPath": + return "p2trMusig2"; + } +} + /** * Creates a valid PSBT with as many features as possible (kitchen sink). * @@ -158,6 +175,7 @@ export class AcidTest { ): AcidTest { const rootWalletKeys = getDefaultWalletKeys(); const otherWalletKeys = getWalletKeysForSeed("too many secrets"); + const coin = network; // Filter inputs based on network support const inputs: Input[] = inputScriptTypes @@ -167,9 +185,9 @@ export class AcidTest { // Map input script types to output script types for support check if (scriptType === "p2trMusig2KeyPath" || scriptType === "p2trMusig2ScriptPath") { - return supportsScriptType(network, "p2trMusig2"); + return supportsScriptType(coin, "p2trMusig2"); } - return supportsScriptType(network, scriptType); + return supportsScriptType(coin, scriptType); }) .filter( (scriptType) => @@ -183,7 +201,7 @@ export class AcidTest { // Filter outputs based on network support const outputs: Output[] = outputScriptTypes - .filter((scriptType) => supportsScriptType(network, scriptType)) + .filter((scriptType) => supportsScriptType(coin, scriptType)) .map((scriptType, index) => ({ scriptType, value: BigInt(900 + index * 100), // Deterministic amounts @@ -234,66 +252,80 @@ export class AcidTest { // Use ZcashBitGoPsbt for Zcash networks const isZcash = this.network === "zec" || this.network === "tzec"; const psbt = isZcash - ? ZcashBitGoPsbt.createEmptyWithConsensusBranchId(this.network, this.rootWalletKeys, { - version: 2, - lockTime: 0, - consensusBranchId: 0xc2d6d0b4, // NU5 + ? ZcashBitGoPsbt.createEmpty(this.network, this.rootWalletKeys, { + // Sapling activation height: mainnet=419200, testnet=280000 + blockHeight: this.network === "zec" ? 419200 : 280000, }) : BitGoPsbt.createEmpty(this.network, this.rootWalletKeys, { version: 2, lockTime: 0, }); + // Build a fake previous transaction for non_witness_utxo (psbt format) + const usePrevTx = this.txFormat === "psbt" && !isZcash; + const buildPrevTx = ( + vout: number, + script: Uint8Array, + value: bigint, + ): Uint8Array | undefined => { + if (!usePrevTx) return undefined; + const tx = Transaction.create(); + tx.addInput("0".repeat(64), 0xffffffff); + for (let i = 0; i < vout; i++) { + tx.addOutput(new Uint8Array(0), 0n); + } + tx.addOutput(script, value); + return tx.toBytes(); + }; + // Add inputs with deterministic outpoints this.inputs.forEach((input, index) => { - // Resolve scriptId: either from explicit scriptId or from scriptType + index - const scriptId: ScriptId = input.scriptId ?? { - chain: ChainCode.value("p2sh", "external"), - index: input.index ?? index, - }; const walletKeys = input.walletKeys ?? this.rootWalletKeys; + const outpoint = { txid: "0".repeat(64), vout: index, value: input.value }; - // Get scriptType: either explicit or derive from scriptId chain - const scriptType = input.scriptType ?? ChainCode.scriptType(assertChainCode(scriptId.chain)); + // scriptId variant: caller provides explicit chain + index + if (input.scriptId) { + const script = outputScript( + walletKeys, + input.scriptId.chain, + input.scriptId.index, + this.network, + ); + psbt.addWalletInput( + { ...outpoint, prevTx: buildPrevTx(index, script, input.value) }, + walletKeys, + { scriptId: input.scriptId, signPath: { signer: "user", cosigner: "bitgo" } }, + ); + return; + } + + const scriptType = input.scriptType ?? "p2sh"; if (scriptType === "p2shP2pk") { - // Add replay protection input - const replayKey = this.getReplayProtectionKey(); - // Convert BIP32 to ECPair using public key - const ecpair = ECPair.fromPublicKey(replayKey.publicKey); + const ecpair = ECPair.fromPublicKey(this.getReplayProtectionKey().publicKey); + const script = p2shP2pkOutputScript(ecpair.publicKey); psbt.addReplayProtectionInput( - { - txid: "0".repeat(64), - vout: index, - value: input.value, - }, + { ...outpoint, prevTx: buildPrevTx(index, script, input.value) }, ecpair, ); - } else { - // Determine signing path based on input type - let signPath: { signer: SignerKey; cosigner: SignerKey }; - - if (scriptType === "p2trMusig2ScriptPath") { - // Script path uses user + backup - signPath = { signer: "user", cosigner: "backup" }; - } else { - // Default: user + bitgo - signPath = { signer: "user", cosigner: "bitgo" }; - } - - psbt.addWalletInput( - { - txid: "0".repeat(64), - vout: index, - value: input.value, - }, - walletKeys, - { - scriptId, - signPath, - }, - ); + return; } + + const scriptId: ScriptId = { + chain: ChainCode.value(inputScriptTypeToOutputScriptType(scriptType), "external"), + index: input.index ?? index, + }; + const signPath: { signer: SignerKey; cosigner: SignerKey } = + scriptType === "p2trMusig2ScriptPath" + ? { signer: "user", cosigner: "backup" } + : { signer: "user", cosigner: "bitgo" }; + const script = outputScript(walletKeys, scriptId.chain, scriptId.index, this.network); + + psbt.addWalletInput( + { ...outpoint, prevTx: buildPrevTx(index, script, input.value) }, + walletKeys, + { scriptId, signPath }, + ); }); // Add outputs @@ -366,40 +398,27 @@ export class AcidTest { ); if (hasMusig2Inputs) { - const isZcash = this.network === "zec" || this.network === "tzec"; - if (isZcash) { + if (this.network === "zec" || this.network === "tzec") { throw new Error("Zcash does not support MuSig2/Taproot inputs"); } - // Generate nonces with user key + // MuSig2 requires ALL participant nonces before ANY signing. + // Generate nonces directly on the same PSBT for each participant key. psbt.generateMusig2Nonces(userKey); - if (this.signStage === "fullsigned") { - // Create a second PSBT with cosigner nonces for combination - // For p2trMusig2ScriptPath use backup, for p2trMusig2KeyPath use bitgo - // Since we might have both types, we need to generate nonces separately - const bytes = psbt.serialize(); - - const hasKeyPath = this.inputs.some((input) => input.scriptType === "p2trMusig2KeyPath"); - const hasScriptPath = this.inputs.some( - (input) => input.scriptType === "p2trMusig2ScriptPath", - ); + const hasKeyPath = this.inputs.some((input) => input.scriptType === "p2trMusig2KeyPath"); + const hasScriptPath = this.inputs.some( + (input) => input.scriptType === "p2trMusig2ScriptPath", + ); - if (hasKeyPath && !hasScriptPath) { - // Only key path inputs - generate bitgo nonces for all - const psbt2 = BitGoPsbt.fromBytes(bytes, this.network); - psbt2.generateMusig2Nonces(bitgoKey); - psbt.combineMusig2Nonces(psbt2); - } else if (hasScriptPath && !hasKeyPath) { - // Only script path inputs - generate backup nonces for all - const psbt2 = BitGoPsbt.fromBytes(bytes, this.network); - psbt2.generateMusig2Nonces(backupKey); - psbt.combineMusig2Nonces(psbt2); - } else { - const psbt2 = BitGoPsbt.fromBytes(bytes, this.network); - psbt2.generateMusig2Nonces(bitgoKey); - psbt.combineMusig2Nonces(psbt2); - } + // Key path uses user+bitgo, script path uses user+backup. + // generateMusig2Nonces fails if the key isn't a participant in any musig2 input, + // so we only call it for keys that match. + if (hasKeyPath) { + psbt.generateMusig2Nonces(bitgoKey); + } + if (hasScriptPath) { + psbt.generateMusig2Nonces(backupKey); } } @@ -446,8 +465,8 @@ export class AcidTest { * Generate test suite for all networks, sign stages, and tx formats */ static forAllNetworksSignStagesTxFormats(suiteConfig: SuiteConfig = {}): AcidTest[] { - return (coinNames as readonly CoinName[]) - .filter((network) => isMainnet(network) && network !== "bsv") // Exclude bitcoinsv + return coinNames + .filter((network): network is CoinName => isMainnet(network) && network !== "bsv") .flatMap((network) => signStages.flatMap((signStage) => txFormats.map((txFormat) => diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs index 3e46924e..28591da6 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/mod.rs @@ -3034,10 +3034,11 @@ mod tests { }); fn test_parse_with_format(format: fixtures::TxFormat, network: Network) { - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Unsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .unwrap(); match fixture.to_bitgo_psbt(network) { @@ -3160,10 +3161,11 @@ mod tests { } fn test_round_trip_with_format(format: fixtures::TxFormat, network: Network) { - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Unsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .unwrap(); @@ -3589,7 +3591,7 @@ mod tests { network: Network, tx_format: fixtures::TxFormat, ) -> Result<(), String> { - let psbt_stages = fixtures::PsbtStages::load(network, tx_format)?; + let psbt_stages = fixtures::PsbtStages::load_utxolib_compat(network, tx_format)?; let psbt_input_stages = fixtures::PsbtInputStages::from_psbt_stages(&psbt_stages, script_type); @@ -3757,10 +3759,11 @@ mod tests { ); crate::test_psbt_fixtures!(test_extract_transaction, network, format, { - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Fullsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .expect("Failed to load fixture"); let mut bitgo_psbt = fixture @@ -3814,10 +3817,11 @@ mod tests { } // Load halfsigned fixture - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Halfsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .map_err(|e| format!("Failed to load halfsigned fixture: {}", e))?; @@ -4144,10 +4148,11 @@ mod tests { crate::test_psbt_fixtures!(test_parse_transaction_with_wallet_keys, network, format, { // Load fixture and get PSBT - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Unsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .expect("Failed to load fixture"); @@ -4282,9 +4287,11 @@ mod tests { #[test] fn test_serialize_zcash_psbt() { // Test that Zcash PSBTs can be serialized - let fixture = fixtures::load_psbt_fixture_with_network( - Network::Zcash, + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( + "zcash", fixtures::SignatureState::Unsigned, + fixtures::TxFormat::Psbt, + fixtures::FixtureNamespace::UtxolibCompat, ) .unwrap(); let original_bytes = BASE64_STANDARD @@ -4304,10 +4311,11 @@ mod tests { use crate::fixed_script_wallet::ReplayProtection; // Load fixture with specified format - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Unsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .expect("Failed to load fixture"); diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/p2tr_musig2_input.rs b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/p2tr_musig2_input.rs index 4c996acd..27f83834 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/p2tr_musig2_input.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/p2tr_musig2_input.rs @@ -1296,7 +1296,8 @@ mod tests { use super::*; use crate::fixed_script_wallet::test_utils::fixtures; use crate::fixed_script_wallet::test_utils::fixtures::{ - load_psbt_fixture_with_format, ScriptType, SignatureState, TxFormat, + load_psbt_fixture_with_format_and_namespace, FixtureNamespace, ScriptType, SignatureState, + TxFormat, }; use crate::Network; @@ -1312,8 +1313,13 @@ mod tests { fn get_musig2_fixture_data( signature_state: SignatureState, ) -> Result { - let fixture = load_psbt_fixture_with_format("bitcoin", signature_state, TxFormat::Psbt) - .expect("Failed to load fixture"); + let fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + signature_state, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load fixture"); let (input_index, input_fixture) = fixture .find_input_with_script_type(ScriptType::P2trMusig2TaprootKeypath) @@ -1363,7 +1369,7 @@ mod tests { fixture, musig2_input, musig2_input_index, - fixture_keypath_input, + fixture_keypath_input: _, fixture_keypath_final_input, } = musig2_fixture_data; @@ -1388,18 +1394,12 @@ mod tests { assert_eq!(fixture_witness_bytes[1], 0x40, "Expected 64-byte signature"); let fixture_signature = &fixture_witness_bytes[2..66]; - // Get tap merkle root from fixture + // Get tap merkle root from PSBT input (more reliable than fixture JSON) use crate::bitcoin::sighash::SighashCache; - use crate::bitcoin::taproot::TapNodeHash; - let tap_tree_root_bytes = - as hex::FromHex>::from_hex(&fixture_keypath_input.tap_merkle_root) - .expect("Failed to decode tap merkle root"); - let tap_tree_root_array: [u8; 32] = tap_tree_root_bytes - .as_slice() - .try_into() - .expect("Invalid tap merkle root length"); - let tap_tree_root = TapNodeHash::from_byte_array(tap_tree_root_array); + let tap_tree_root = psbt.inputs[*musig2_input_index] + .tap_merkle_root + .expect("Expected tap_merkle_root in PSBT input"); // Collect all prevouts for sighash computation let prevouts = collect_prevouts(&psbt).expect("Failed to collect prevouts"); @@ -1463,8 +1463,9 @@ mod tests { #[test] fn test_state_machine_api_produces_valid_signature() { // Load fixtures using PsbtStages to get wallet keys - let psbt_stages = fixtures::PsbtStages::load(crate::Network::Bitcoin, TxFormat::Psbt) - .expect("Failed to load PSBT stages"); + let psbt_stages = + fixtures::PsbtStages::load_utxolib_compat(crate::Network::Bitcoin, TxFormat::Psbt) + .expect("Failed to load PSBT stages"); // Find MuSig2 keypath input let (input_index, _input_fixture) = psbt_stages @@ -1497,8 +1498,9 @@ mod tests { // This test validates that both APIs can produce valid signatures on the same input // Load fixtures using PsbtStages to get wallet keys - let psbt_stages = fixtures::PsbtStages::load(crate::Network::Bitcoin, TxFormat::Psbt) - .expect("Failed to load PSBT stages"); + let psbt_stages = + fixtures::PsbtStages::load_utxolib_compat(crate::Network::Bitcoin, TxFormat::Psbt) + .expect("Failed to load PSBT stages"); let (input_index, _) = psbt_stages .unsigned @@ -1549,8 +1551,9 @@ mod tests { use miniscript::bitcoin::psbt::PsbtSighashType; // Load fixtures using PsbtStages to get wallet keys - let psbt_stages = fixtures::PsbtStages::load(crate::Network::Bitcoin, TxFormat::Psbt) - .expect("Failed to load PSBT stages"); + let psbt_stages = + fixtures::PsbtStages::load_utxolib_compat(crate::Network::Bitcoin, TxFormat::Psbt) + .expect("Failed to load PSBT stages"); // Find MuSig2 keypath input let (input_index, _input_fixture) = psbt_stages @@ -1681,8 +1684,9 @@ mod tests { use crate::bitcoin::sighash::TapSighashType; // Load fixtures using PsbtStages to get wallet keys - let psbt_stages = fixtures::PsbtStages::load(crate::Network::Bitcoin, TxFormat::Psbt) - .expect("Failed to load PSBT stages"); + let psbt_stages = + fixtures::PsbtStages::load_utxolib_compat(crate::Network::Bitcoin, TxFormat::Psbt) + .expect("Failed to load PSBT stages"); // Find MuSig2 keypath input let (input_index, _input_fixture) = psbt_stages diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/psbt_wallet_input.rs b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/psbt_wallet_input.rs index 094f7d78..bb1d7319 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/psbt_wallet_input.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/psbt_wallet_input.rs @@ -1274,10 +1274,11 @@ pub mod test_helpers { ]); // Load fixture and extract psbt and wallet keys - let fixture = fixtures::load_psbt_fixture_with_format( + let fixture = fixtures::load_psbt_fixture_with_format_and_namespace( network.to_utxolib_name(), fixtures::SignatureState::Unsigned, format, + fixtures::FixtureNamespace::UtxolibCompat, ) .expect("Failed to load fixture"); let psbt_bytes = fixture.to_psbt_bytes().expect("Failed to get PSBT bytes"); diff --git a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs index f807a5fa..9aaa118d 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/bitgo_psbt/zcash_psbt.rs @@ -434,13 +434,18 @@ mod tests { #[test] fn test_round_trip_zcash_psbt() { use crate::fixed_script_wallet::test_utils::fixtures::{ - load_psbt_fixture_with_network, SignatureState, + load_psbt_fixture_with_format_and_namespace, FixtureNamespace, SignatureState, TxFormat, }; use crate::networks::Network; - // Load the Zcash fixture - let fixture = load_psbt_fixture_with_network(Network::Zcash, SignatureState::Unsigned) - .expect("Failed to load Zcash fixture"); + // Load the Zcash fixture from utxolib-compat + let fixture = load_psbt_fixture_with_format_and_namespace( + "zcash", + SignatureState::Unsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load Zcash fixture"); // Deserialize from fixture let original_bytes = BASE64_STANDARD.decode(&fixture.psbt_base64).unwrap(); diff --git a/packages/wasm-utxo/src/fixed_script_wallet/test_utils/fixtures.rs b/packages/wasm-utxo/src/fixed_script_wallet/test_utils/fixtures.rs index f8ce8c9e..5ff696d8 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/test_utils/fixtures.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/test_utils/fixtures.rs @@ -8,7 +8,7 @@ //! use wasm_miniscript::fixed_script_wallet::test_utils::fixtures::*; //! //! // Load a fixture by network and signature state -//! let fixture = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) +//! let fixture = load_psbt_fixture("btc", SignatureState::Fullsigned) //! .expect("Failed to load fixture"); //! //! // Parse the PSBT from base64 @@ -121,7 +121,8 @@ pub struct WitnessUtxo { pub struct Bip32Derivation { pub pubkey: String, pub path: String, - pub master_fingerprint: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub master_fingerprint: Option, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -141,10 +142,12 @@ pub struct TapLeafScript { #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct TapBip32Derivation { + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub leaf_hashes: Vec, pub pubkey: String, pub path: String, - pub master_fingerprint: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub master_fingerprint: Option, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -308,7 +311,8 @@ pub struct P2shInput { pub witness_utxo: Option, pub sighash_type: u32, pub bip32_derivation: Vec, - pub redeem_script: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub redeem_script: Option, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub partial_sig: Vec, } @@ -320,8 +324,10 @@ pub struct P2shP2wshInput { pub witness_utxo: WitnessUtxo, pub sighash_type: u32, pub bip32_derivation: Vec, - pub witness_script: String, - pub redeem_script: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub witness_script: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub redeem_script: Option, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub partial_sig: Vec, } @@ -333,7 +339,8 @@ pub struct P2wshInput { pub witness_utxo: WitnessUtxo, pub sighash_type: u32, pub bip32_derivation: Vec, - pub witness_script: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub witness_script: Option, #[serde(default, skip_serializing_if = "Vec::is_empty")] pub partial_sig: Vec, } @@ -344,6 +351,7 @@ pub struct P2trScriptPathInput { pub unknown_key_vals: Option>, pub witness_utxo: WitnessUtxo, pub sighash_type: u32, + #[serde(default, skip_serializing_if = "Vec::is_empty")] pub tap_leaf_script: Vec, pub tap_bip32_derivation: Vec, #[serde(default, skip_serializing_if = "Vec::is_empty")] @@ -356,8 +364,10 @@ pub struct P2trMusig2KeyPathInput { pub unknown_key_vals: Option>, pub witness_utxo: WitnessUtxo, pub sighash_type: u32, - pub tap_internal_key: String, - pub tap_merkle_root: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tap_internal_key: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub tap_merkle_root: Option, pub tap_bip32_derivation: Vec, #[serde(skip_serializing_if = "Option::is_none")] pub musig2_participants: Option, @@ -371,7 +381,8 @@ pub struct P2trMusig2KeyPathInput { #[serde(rename_all = "camelCase")] pub struct P2shP2pkInput { pub unknown_key_vals: Option>, - pub redeem_script: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub redeem_script: Option, /// Skipped for PSBT-LITE format pub non_witness_utxo: Option, /// Present for PSBT-LITE format @@ -553,23 +564,44 @@ pub struct PsbtStages { } impl PsbtStages { + /// Load native (AcidTest-generated) fixtures using CoinName filenames. pub fn load(network: Network, tx_format: TxFormat) -> Result { - let unsigned = load_psbt_fixture_with_format( - network.to_utxolib_name(), + Self::load_with_namespace(network, tx_format, FixtureNamespace::Native) + } + + /// Load utxolib-compat fixtures using utxolib network names. + pub fn load_utxolib_compat(network: Network, tx_format: TxFormat) -> Result { + Self::load_with_namespace(network, tx_format, FixtureNamespace::UtxolibCompat) + } + + fn load_with_namespace( + network: Network, + tx_format: TxFormat, + namespace: FixtureNamespace, + ) -> Result { + let network_name = match namespace { + FixtureNamespace::UtxolibCompat => network.to_utxolib_name(), + FixtureNamespace::Native => network.to_coin_name(), + }; + let unsigned = load_psbt_fixture_with_format_and_namespace( + network_name, SignatureState::Unsigned, tx_format, + namespace, ) .expect("Failed to load unsigned fixture"); - let halfsigned = load_psbt_fixture_with_format( - network.to_utxolib_name(), + let halfsigned = load_psbt_fixture_with_format_and_namespace( + network_name, SignatureState::Halfsigned, tx_format, + namespace, ) .expect("Failed to load halfsigned fixture"); - let fullsigned = load_psbt_fixture_with_format( - network.to_utxolib_name(), + let fullsigned = load_psbt_fixture_with_format_and_namespace( + network_name, SignatureState::Fullsigned, tx_format, + namespace, ) .expect("Failed to load fullsigned fixture"); let wallet_keys_unsigned = unsigned @@ -731,7 +763,7 @@ pub struct OutputScriptFixture { /// ```rust,no_run /// use wasm_miniscript::fixed_script_wallet::test_utils::fixtures::*; /// -/// let contents = load_fixture("fixed-script/psbt.bitcoin.fullsigned.json") +/// let contents = load_fixture("fixed-script/psbt.btc.fullsigned.json") /// .expect("Failed to load fixture"); /// ``` pub fn load_fixture(path: &str) -> Result> { @@ -773,23 +805,23 @@ impl TxFormat { } } -/// Load a PSBT fixture from a JSON file -/// -/// # Arguments -/// * `network_name` - The network name (e.g., "bitcoin", "litecoin", "dogecoin") -/// * `signature_state` - The signature state of the PSBT -/// -/// # Example -/// ```rust,no_run -/// use wasm_miniscript::fixed_script_wallet::test_utils::fixtures::*; -/// -/// let fixture = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) -/// .expect("Failed to load fixture"); -/// ``` -pub fn load_psbt_fixture_with_format( +/// Fixture namespace: utxolib-compat (old rich format) or native (AcidTest-generated). +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FixtureNamespace { + /// Old utxo-lib generated fixtures with rich per-input metadata. + /// Uses utxolib network names (bitcoin, litecoin, etc.). + UtxolibCompat, + /// New AcidTest-generated fixtures with simpler format. + /// Uses CoinName filenames (btc, ltc, etc.). + Native, +} + +/// Load a PSBT fixture from a JSON file in the given namespace. +pub fn load_psbt_fixture_with_format_and_namespace( network_name: &str, signature_state: SignatureState, tx_format: TxFormat, + namespace: FixtureNamespace, ) -> Result> { let filename = format!( "{}.{}.{}.json", @@ -797,32 +829,42 @@ pub fn load_psbt_fixture_with_format( network_name, signature_state.as_str() ); - let path = format!("fixed-script/{}", filename); + let path = match namespace { + FixtureNamespace::UtxolibCompat => format!("fixed-script/utxolib-compat/{}", filename), + FixtureNamespace::Native => format!("fixed-script/{}", filename), + }; let contents = - load_fixture(&path).unwrap_or_else(|_| panic!("Failed to load fixture: {}", filename)); + load_fixture(&path).unwrap_or_else(|_| panic!("Failed to load fixture: {}", path)); let fixture: PsbtFixture = serde_json::from_str(&contents)?; Ok(fixture) } -pub fn load_psbt_fixture( +/// Load a native PSBT fixture (AcidTest-generated, CoinName filenames). +pub fn load_psbt_fixture_with_format( network_name: &str, signature_state: SignatureState, + tx_format: TxFormat, ) -> Result> { - load_psbt_fixture_with_format(network_name, signature_state, TxFormat::Psbt) + load_psbt_fixture_with_format_and_namespace( + network_name, + signature_state, + tx_format, + FixtureNamespace::Native, + ) } -pub fn load_psbt_lite_fixture( +pub fn load_psbt_fixture( network_name: &str, signature_state: SignatureState, ) -> Result> { - load_psbt_fixture_with_format(network_name, signature_state, TxFormat::PsbtLite) + load_psbt_fixture_with_format(network_name, signature_state, TxFormat::Psbt) } pub fn load_psbt_fixture_with_network( network: Network, signature_state: SignatureState, ) -> Result> { - load_psbt_fixture(network.to_utxolib_name(), signature_state) + load_psbt_fixture(network.to_coin_name(), signature_state) } /// Load a PSBT fixture from JSON string @@ -922,9 +964,11 @@ impl P2shInput { let generated_output = scripts.redeem_script.to_p2sh().to_hex_string(); assert_hex_eq(&generated_output, output_script, "Output script")?; - // Compare redeem script - let redeem_script_hex = scripts.redeem_script.to_hex_string(); - assert_hex_eq(&redeem_script_hex, &self.redeem_script, "Redeem script")?; + // Compare redeem script (when present in fixture) + if let Some(expected) = &self.redeem_script { + let redeem_script_hex = scripts.redeem_script.to_hex_string(); + assert_hex_eq(&redeem_script_hex, expected, "Redeem script")?; + } validate_sighash_type_fixture(self.sighash_type, network) } @@ -942,13 +986,17 @@ impl P2shP2wshInput { let generated_output = scripts.redeem_script.to_p2sh().to_hex_string(); assert_hex_eq(&generated_output, output_script, "Output script")?; - // Compare redeem script - let redeem_script_hex = scripts.redeem_script.to_hex_string(); - assert_hex_eq(&redeem_script_hex, &self.redeem_script, "Redeem script")?; + // Compare redeem script (when present in fixture) + if let Some(expected) = &self.redeem_script { + let redeem_script_hex = scripts.redeem_script.to_hex_string(); + assert_hex_eq(&redeem_script_hex, expected, "Redeem script")?; + } - // Compare witness script - let witness_script_hex = scripts.witness_script.to_hex_string(); - assert_hex_eq(&witness_script_hex, &self.witness_script, "Witness script")?; + // Compare witness script (when present in fixture) + if let Some(expected) = &self.witness_script { + let witness_script_hex = scripts.witness_script.to_hex_string(); + assert_hex_eq(&witness_script_hex, expected, "Witness script")?; + } validate_sighash_type_fixture(self.sighash_type, network) } @@ -966,9 +1014,11 @@ impl P2wshInput { let generated_output = scripts.witness_script.to_p2wsh().to_hex_string(); assert_hex_eq(&generated_output, output_script, "Output script")?; - // Compare witness script - let witness_script_hex = scripts.witness_script.to_hex_string(); - assert_hex_eq(&witness_script_hex, &self.witness_script, "Witness script")?; + // Compare witness script (when present in fixture) + if let Some(expected) = &self.witness_script { + let witness_script_hex = scripts.witness_script.to_hex_string(); + assert_hex_eq(&witness_script_hex, expected, "Witness script")?; + } validate_sighash_type_fixture(self.sighash_type, network) } @@ -1040,17 +1090,21 @@ impl P2trMusig2KeyPathInput { spend_info: &crate::bitcoin::taproot::TaprootSpendInfo, network: Network, ) -> Result<(), String> { - // Compare internal key - let internal_key_hex = hex::encode(spend_info.internal_key().serialize()); - assert_hex_eq(&internal_key_hex, &self.tap_internal_key, "Internal key")?; - - // Compare merkle root - let merkle_root = spend_info - .merkle_root() - .ok_or_else(|| "Expected merkle root to exist".to_string())?; - let merkle_root_bytes: &[u8] = merkle_root.as_ref(); - let merkle_root_hex = hex::encode(merkle_root_bytes); - assert_hex_eq(&merkle_root_hex, &self.tap_merkle_root, "Merkle root")?; + // Compare internal key (when present in fixture) + if let Some(expected) = &self.tap_internal_key { + let internal_key_hex = hex::encode(spend_info.internal_key().serialize()); + assert_hex_eq(&internal_key_hex, expected, "Internal key")?; + } + + // Compare merkle root (when present in fixture) + if let Some(expected) = &self.tap_merkle_root { + let merkle_root = spend_info + .merkle_root() + .ok_or_else(|| "Expected merkle root to exist".to_string())?; + let merkle_root_bytes: &[u8] = merkle_root.as_ref(); + let merkle_root_hex = hex::encode(merkle_root_bytes); + assert_hex_eq(&merkle_root_hex, expected, "Merkle root")?; + } validate_sighash_type_fixture(self.sighash_type, network) } @@ -1399,8 +1453,8 @@ mod tests { #[test] fn test_load_fixture_helper() { // Test loading a fixture file - let contents = load_fixture("fixed-script/psbt.bitcoin.fullsigned.json") - .expect("Failed to load fixture"); + let contents = + load_fixture("fixed-script/psbt.btc.fullsigned.json").expect("Failed to load fixture"); assert!(!contents.is_empty()); assert!(contents.contains("walletKeys")); assert!(contents.contains("psbtBase64")); @@ -1422,12 +1476,15 @@ mod tests { } #[test] - fn test_load_bitcoin_fullsigned_fixture() { - // Example of loading a fixture file - let fixture = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) - .expect("Failed to load fixture"); + fn test_load_utxolib_compat_fixture() { + let fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + SignatureState::Fullsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load fixture"); - // Verify structure assert_eq!(fixture.wallet_keys.len(), 3); assert!(!fixture.psbt_base64.is_empty()); assert_eq!(fixture.inputs.len(), 7); @@ -1435,36 +1492,32 @@ mod tests { assert_eq!(fixture.outputs.len(), 8); assert_eq!(fixture.psbt_outputs.len(), 8); - // Decode PSBT let psbt = decode_psbt_from_fixture(&fixture).expect("Failed to decode PSBT"); assert_eq!(psbt.inputs.len(), 7); assert_eq!(psbt.outputs.len(), 8); } #[test] - fn test_load_different_signature_states() { - // Test unsigned - let unsigned = load_psbt_fixture("bitcoin", SignatureState::Unsigned) - .expect("Failed to load unsigned fixture"); - assert_eq!(unsigned.inputs.len(), 7); - assert_eq!(unsigned.psbt_inputs.len(), 7); - - // Test halfsigned - let halfsigned = load_psbt_fixture("bitcoin", SignatureState::Halfsigned) - .expect("Failed to load halfsigned fixture"); - assert_eq!(halfsigned.inputs.len(), 7); - assert_eq!(halfsigned.psbt_inputs.len(), 7); - - // Test fullsigned - let fullsigned = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) - .expect("Failed to load fullsigned fixture"); - assert_eq!(fullsigned.inputs.len(), 7); - assert_eq!(fullsigned.psbt_inputs.len(), 7); + fn test_load_utxolib_compat_signature_states() { + for state in [ + SignatureState::Unsigned, + SignatureState::Halfsigned, + SignatureState::Fullsigned, + ] { + let fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + state, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load fixture"); + assert_eq!(fixture.inputs.len(), 7); + assert_eq!(fixture.psbt_inputs.len(), 7); + } } #[test] - fn test_load_different_networks() { - // Test various networks + fn test_load_utxolib_compat_networks() { for network in &[ "bitcoin", "litecoin", @@ -1474,6 +1527,28 @@ mod tests { "dash", "bitcoingold", ] { + let fixture = load_psbt_fixture_with_format_and_namespace( + network, + SignatureState::Fullsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .unwrap_or_else(|_| panic!("Failed to load {} fixture", network)); + assert_eq!(fixture.wallet_keys.len(), 3); + } + } + + #[test] + fn test_load_native_fixture() { + let fixture = + load_psbt_fixture("btc", SignatureState::Fullsigned).expect("Failed to load fixture"); + assert_eq!(fixture.wallet_keys.len(), 3); + assert!(!fixture.psbt_base64.is_empty()); + } + + #[test] + fn test_load_native_networks() { + for network in &["btc", "ltc", "doge", "bch", "bcha", "dash", "btg"] { let fixture = load_psbt_fixture(network, SignatureState::Fullsigned) .unwrap_or_else(|_| panic!("Failed to load {} fixture", network)); assert_eq!(fixture.wallet_keys.len(), 3); @@ -1503,8 +1578,13 @@ mod tests { #[test] fn test_find_input_with_script_type() { - let fixture = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) - .expect("Failed to load fixture"); + let fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + SignatureState::Fullsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load fixture"); // Test finding P2SH input let (index, input) = fixture @@ -1523,8 +1603,13 @@ mod tests { #[test] fn test_find_finalized_input_with_script_type() { - let fixture = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) - .expect("Failed to load fixture"); + let fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + SignatureState::Fullsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load fixture"); // Test finding P2SH finalized input let (index, input) = fixture @@ -1541,8 +1626,13 @@ mod tests { assert!(matches!(input, PsbtFinalInputFixture::P2trMusig2KeyPath(_))); // Test with unsigned fixture (should return error) - let unsigned_fixture = load_psbt_fixture("bitcoin", SignatureState::Unsigned) - .expect("Failed to load unsigned fixture"); + let unsigned_fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + SignatureState::Unsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load unsigned fixture"); let result = unsigned_fixture.find_finalized_input_with_script_type(ScriptType::P2sh); assert!(result.is_err()); assert_eq!( diff --git a/packages/wasm-utxo/src/fixed_script_wallet/test_utils/psbt_compare.rs b/packages/wasm-utxo/src/fixed_script_wallet/test_utils/psbt_compare.rs index c5299a56..bf1d3c51 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/test_utils/psbt_compare.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/test_utils/psbt_compare.rs @@ -481,7 +481,7 @@ mod tests { use crate::fixed_script_wallet::test_utils::fixtures; let fixture = fixtures::load_psbt_fixture_with_format( - "bitcoin", + "btc", fixtures::SignatureState::Unsigned, fixtures::TxFormat::Psbt, ) @@ -504,7 +504,7 @@ mod tests { use crate::fixed_script_wallet::test_utils::fixtures; let fixture = fixtures::load_psbt_fixture_with_format( - "bitcoin", + "btc", fixtures::SignatureState::Unsigned, fixtures::TxFormat::Psbt, ) @@ -521,14 +521,14 @@ mod tests { use crate::fixed_script_wallet::test_utils::fixtures; let unsigned = fixtures::load_psbt_fixture_with_format( - "bitcoin", + "btc", fixtures::SignatureState::Unsigned, fixtures::TxFormat::Psbt, ) .expect("Failed to load unsigned fixture"); let fullsigned = fixtures::load_psbt_fixture_with_format( - "bitcoin", + "btc", fixtures::SignatureState::Fullsigned, fixtures::TxFormat::Psbt, ) diff --git a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs index 27519320..b1ae45ca 100644 --- a/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs +++ b/packages/wasm-utxo/src/fixed_script_wallet/wallet_scripts/singlesig.rs @@ -35,12 +35,19 @@ mod tests { use super::*; use crate::bitcoin::secp256k1::Secp256k1; - use crate::fixed_script_wallet::test_utils::fixtures::{load_psbt_fixture, SignatureState}; + use crate::fixed_script_wallet::test_utils::fixtures::{ + load_psbt_fixture_with_format_and_namespace, FixtureNamespace, SignatureState, TxFormat, + }; #[test] fn test_p2sh_p2pk_script_generation_from_fixture() { - let fixture = load_psbt_fixture("bitcoin", SignatureState::Fullsigned) - .expect("Failed to load fixture"); + let fixture = load_psbt_fixture_with_format_and_namespace( + "bitcoin", + SignatureState::Fullsigned, + TxFormat::Psbt, + FixtureNamespace::UtxolibCompat, + ) + .expect("Failed to load fixture"); // Find the p2shP2pk input in the fixture let p2shp2pk_input = fixture @@ -72,12 +79,14 @@ mod tests { // Build the p2sh-p2pk script let script = ScriptP2shP2pk::new(pubkey); - // Verify the redeem script matches - assert_eq!( - script.redeem_script.to_hex_string(), - *expected_redeem_script, - "Redeem script mismatch" - ); + // Verify the redeem script matches (when present in fixture) + if let Some(expected) = expected_redeem_script { + assert_eq!( + script.redeem_script.to_hex_string(), + *expected, + "Redeem script mismatch" + ); + } // Verify the output script (p2sh wrapped) matches the fixture // Get the output script from the non-witness UTXO diff --git a/packages/wasm-utxo/test/dimensions.ts b/packages/wasm-utxo/test/dimensions.ts index cbc1c085..bdb808d6 100644 --- a/packages/wasm-utxo/test/dimensions.ts +++ b/packages/wasm-utxo/test/dimensions.ts @@ -1,5 +1,4 @@ import assert from "node:assert"; -import * as utxolib from "@bitgo/utxo-lib"; import { Dimensions, fixedScriptWallet } from "../js/index.js"; import { Transaction } from "../js/transaction.js"; import { @@ -8,7 +7,7 @@ import { type Fixture, type Output, } from "./fixedScript/fixtureUtil.js"; -import { getFixtureNetworks } from "./fixedScript/networkSupport.util.js"; +import { mainnetCoinNames } from "./fixedScript/networkSupport.util.js"; import type { InputScriptType } from "../js/fixedScriptWallet/BitGoPsbt.js"; /** @@ -383,16 +382,14 @@ describe("Dimensions", function () { describe("integration tests with fixtures", function () { // Zcash has additional transaction overhead (version group, expiry height, etc.) // that we don't account for in Dimensions - skip it for now - const networksToTest = getFixtureNetworks().filter((n) => n !== utxolib.networks.zcash); - - networksToTest.forEach((network) => { - const networkName = utxolib.getNetworkName(network); + const networksToTest = mainnetCoinNames.filter((n) => n !== "zec"); + networksToTest.forEach((networkName) => { describe(`${networkName}`, function () { let fixture: Fixture; - before(function () { - fixture = loadPsbtFixture(networkName, "fullsigned"); + before(async function () { + fixture = await loadPsbtFixture(networkName, "fullsigned"); }); it("actual vSize is within estimated min/max bounds", function () { @@ -432,48 +429,25 @@ describe("Dimensions", function () { }); describe("manual construction test", function () { - it("builds correct dimensions for bitcoin fixture", function () { - const fixture = loadPsbtFixture("bitcoin", "fullsigned"); + it("builds correct dimensions for bitcoin fixture", async function () { + const fixture = await loadPsbtFixture("btc", "fullsigned"); if (!fixture.extractedTransaction) { return; } - // Build dimensions based on fixture input types: - // 0: p2sh, 1: p2shP2wsh, 2: p2wsh, 3: p2tr (script), - // 4: p2trMusig2 (script path), 5: p2trMusig2 (keypath), 6: p2shP2pk - let dim = Dimensions.empty() - .plus(Dimensions.fromInput({ chain: 0 })) // p2sh - .plus(Dimensions.fromInput({ chain: 11 })) // p2shP2wsh - .plus(Dimensions.fromInput({ chain: 21 })) // p2wsh - .plus(Dimensions.fromInput({ chain: 31 })) // p2tr script path level 1 - .plus( - Dimensions.fromInput({ - chain: 41, - signPath: { signer: "user", cosigner: "backup" }, - }), - ) // p2trMusig2 script path - .plus(Dimensions.fromInput({ chain: 41 })) // p2trMusig2 keypath - .plus(Dimensions.fromInput({ scriptType: "p2shP2pk" })); // replay protection + // Build dimensions from fixture psbtInputs (adapts to AcidTest structure) + let dim = Dimensions.empty(); + for (const psbtInput of fixture.psbtInputs) { + const scriptType = fixtureTypeToInputScriptType(psbtInput.type); + if (scriptType === null) { + throw new Error(`Unknown input type: ${psbtInput.type}`); + } + dim = dim.plus(Dimensions.fromInput({ scriptType })); + } // Add outputs dim = dim.plus(dimensionsFromOutputs(fixture.outputs)); - // Build dimensions using scriptType - let dimFromTypes = Dimensions.empty() - .plus(Dimensions.fromInput({ scriptType: "p2sh" })) - .plus(Dimensions.fromInput({ scriptType: "p2shP2wsh" })) - .plus(Dimensions.fromInput({ scriptType: "p2wsh" })) - .plus(Dimensions.fromInput({ scriptType: "p2trLegacy" })) - .plus(Dimensions.fromInput({ scriptType: "p2trMusig2ScriptPath" })) - .plus(Dimensions.fromInput({ scriptType: "p2trMusig2KeyPath" })) - .plus(Dimensions.fromInput({ scriptType: "p2shP2pk" })); - - dimFromTypes = dimFromTypes.plus(dimensionsFromOutputs(fixture.outputs)); - - // Both methods should produce same weights - assert.strictEqual(dim.getWeight("min"), dimFromTypes.getWeight("min")); - assert.strictEqual(dim.getWeight("max"), dimFromTypes.getWeight("max")); - // Get actual vSize const txBytes = Buffer.from(fixture.extractedTransaction, "hex"); const actualVSize = Transaction.fromBytes(txBytes).getVSize(); @@ -492,14 +466,12 @@ describe("Dimensions", function () { describe("fromPsbt", function () { // Zcash has additional transaction overhead that we don't account for - const networksToTest = getFixtureNetworks().filter((n) => n !== utxolib.networks.zcash); - - networksToTest.forEach((network) => { - const networkName = utxolib.getNetworkName(network); + const networksToTest = mainnetCoinNames.filter((n) => n !== "zec"); + networksToTest.forEach((networkName) => { describe(`${networkName}`, function () { - it("actual vSize is within fromPsbt estimated bounds", function () { - const fixture = loadPsbtFixture(networkName, "fullsigned"); + it("actual vSize is within fromPsbt estimated bounds", async function () { + const fixture = await loadPsbtFixture(networkName, "fullsigned"); if (!fixture.extractedTransaction) { this.skip(); return; diff --git a/packages/wasm-utxo/test/fixedScript/finalizeExtract.ts b/packages/wasm-utxo/test/fixedScript/finalizeExtract.ts index 10c532f0..e48f80aa 100644 --- a/packages/wasm-utxo/test/fixedScript/finalizeExtract.ts +++ b/packages/wasm-utxo/test/fixedScript/finalizeExtract.ts @@ -1,5 +1,4 @@ import assert from "node:assert"; -import * as utxolib from "@bitgo/utxo-lib"; import { fixedScriptWallet } from "../../js/index.js"; import { loadPsbtFixture, @@ -7,19 +6,17 @@ import { getExtractedTransactionHex, type Fixture, } from "./fixtureUtil.js"; -import { getFixtureNetworks } from "./networkSupport.util.js"; +import { mainnetCoinNames } from "./networkSupport.util.js"; describe("finalize and extract transaction", function () { - getFixtureNetworks().forEach((network) => { - const networkName = utxolib.getNetworkName(network); - + mainnetCoinNames.forEach((networkName) => { describe(`network: ${networkName}`, function () { let fullsignedFixture: Fixture; let fullsignedPsbtBuffer: Buffer; let fullsignedBitgoPsbt: fixedScriptWallet.BitGoPsbt; - before(function () { - fullsignedFixture = loadPsbtFixture(networkName, "fullsigned"); + before(async function () { + fullsignedFixture = await loadPsbtFixture(networkName, "fullsigned"); fullsignedPsbtBuffer = getPsbtBuffer(fullsignedFixture); fullsignedBitgoPsbt = fixedScriptWallet.BitGoPsbt.fromBytes( fullsignedPsbtBuffer, @@ -108,11 +105,6 @@ describe("finalize and extract transaction", function () { const txid = extractedTx.getId(); assert.strictEqual(txid.length, 64, "txid should be 64 characters"); assert.match(txid, /^[0-9a-f]{64}$/, "txid should be lowercase hex"); - - // Verify txid matches utxolib calculation - const expectedTxHex = getExtractedTransactionHex(fullsignedFixture); - const utxolibTx = utxolib.bitgo.createTransactionFromHex(expectedTxHex, network); - assert.strictEqual(txid, utxolibTx.getId(), "txid should match utxolib calculation"); }); }); }); diff --git a/packages/wasm-utxo/test/fixedScript/fixtureUtil.ts b/packages/wasm-utxo/test/fixedScript/fixtureUtil.ts index 75013cbc..9b939c5b 100644 --- a/packages/wasm-utxo/test/fixedScript/fixtureUtil.ts +++ b/packages/wasm-utxo/test/fixedScript/fixtureUtil.ts @@ -8,7 +8,11 @@ import { BIP32, type BIP32Interface } from "../../js/bip32.js"; import { RootWalletKeys } from "../../js/fixedScriptWallet/RootWalletKeys.js"; import { ECPair } from "../../js/ecpair.js"; import { fixedScriptWallet } from "../../js/index.js"; -import type { BitGoPsbt, NetworkName } from "../../js/fixedScriptWallet/index.js"; +import type { BitGoPsbt } from "../../js/fixedScriptWallet/index.js"; +import type { CoinName } from "../../js/coinName.js"; +import { getFixture } from "../fixtures.js"; +import { generateAllStates } from "./generateFixture.js"; +import type { TxFormat } from "../../js/testutils/AcidTest.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -18,14 +22,11 @@ export type SignatureState = "unsigned" | "halfsigned" | "fullsigned"; export type Triple = [T, T, T]; export type Bip32Derivation = { - masterFingerprint: string; pubkey: string; path: string; }; -export type TapBip32Derivation = Bip32Derivation & { - leafHashes: string[]; -}; +export type TapBip32Derivation = Bip32Derivation; export type WitnessUtxo = { value: string; @@ -111,23 +112,49 @@ export function getPsbtBuffer(fixture: Fixture): Buffer { * @param networkName - The network name for deserializing the PSBT * @returns A BitGoPsbt instance */ -export function getBitGoPsbt(fixture: Fixture, networkName: NetworkName): BitGoPsbt { +export function getBitGoPsbt(fixture: Fixture, networkName: CoinName): BitGoPsbt { return fixedScriptWallet.BitGoPsbt.fromBytes(getPsbtBuffer(fixture), networkName); } -/** - * Load a PSBT fixture from JSON file - */ -export function loadPsbtFixture(network: string, signatureState: string): Fixture { - const fixturePath = path.join( +function getFixturePath( + network: string, + signatureState: string, + txFormat: TxFormat = "psbt-lite", +): string { + return path.join( __dirname, "..", "fixtures", "fixed-script", - `psbt-lite.${network}.${signatureState}.json`, + `${txFormat}.${network}.${signatureState}.json`, ); - const fixtureContent = fs.readFileSync(fixturePath, "utf-8"); - return JSON.parse(fixtureContent) as Fixture; +} + +const SIGNATURE_STATES: SignatureState[] = ["unsigned", "halfsigned", "fullsigned"]; + +/** + * Load a PSBT fixture from JSON file. + * If the fixture does not exist, generates all three signature states + * (unsigned, halfsigned, fullsigned) and writes them to disk. + */ +export async function loadPsbtFixture( + network: CoinName, + signatureState: SignatureState, + txFormat: TxFormat = "psbt-lite", +): Promise { + const fixturePath = getFixturePath(network, signatureState, txFormat); + return getFixture(fixturePath, () => { + const allStates = generateAllStates(network, txFormat); + // Write sibling states so all three are consistent + for (const state of SIGNATURE_STATES) { + if (state !== signatureState) { + const siblingPath = getFixturePath(network, state, txFormat); + fs.mkdirSync(path.dirname(siblingPath), { recursive: true }); + fs.writeFileSync(siblingPath, JSON.stringify(allStates[state], null, 2)); + } + } + return allStates[signatureState]; + }) as Promise; } /** diff --git a/packages/wasm-utxo/test/fixedScript/generateFixture.ts b/packages/wasm-utxo/test/fixedScript/generateFixture.ts new file mode 100644 index 00000000..67389730 --- /dev/null +++ b/packages/wasm-utxo/test/fixedScript/generateFixture.ts @@ -0,0 +1,140 @@ +import { AcidTest, type TxFormat } from "../../js/testutils/AcidTest.js"; +import { getKeyTriple, getWalletKeysForSeed } from "../../js/testutils/keys.js"; +import { ECPair } from "../../js/ecpair.js"; +import { BitGoPsbt, type InputScriptType } from "../../js/fixedScriptWallet/index.js"; +import type { CoinName } from "../../js/coinName.js"; +import { RootWalletKeys } from "../../js/fixedScriptWallet/RootWalletKeys.js"; +import type { + Fixture, + PsbtInput, + PsbtOutput, + Output, + SignatureState, + Bip32Derivation, +} from "./fixtureUtil.js"; + +export function createOtherWalletKeys(): RootWalletKeys { + return getWalletKeysForSeed("too many secrets"); +} + +function toFixtureType(scriptType: InputScriptType): string { + switch (scriptType) { + case "p2sh": + case "p2shP2wsh": + case "p2wsh": + case "p2shP2pk": + return scriptType; + case "p2trLegacy": + return "p2tr"; + case "p2trMusig2ScriptPath": + return "p2trMusig2"; + case "p2trMusig2KeyPath": + return "taprootKeyPathSpend"; + default: + throw new Error(`Unknown script type: ${String(scriptType)}`); + } +} + +function reverseHex(hex: string): string { + return Buffer.from(hex, "hex").reverse().toString("hex"); +} + +function toBip32Derivation(d: { pubkey: Uint8Array; path: string }): Bip32Derivation { + return { + pubkey: Buffer.from(d.pubkey).toString("hex"), + path: d.path, + }; +} + +function snapshotFixture(acid: AcidTest, psbt: BitGoPsbt): Fixture { + const xprivs = getKeyTriple("default"); + const rpBip32 = acid.getReplayProtectionKey(); + const rpKey = ECPair.fromPublicKey(rpBip32.publicKey); + + const parsed = psbt.parseTransactionWithWalletKeys(acid.rootWalletKeys, { + replayProtection: { publicKeys: [rpKey] }, + }); + + const psbtInputData = psbt.getInputs(); + const psbtOutputData = psbt.getOutputs(); + + const inputs = parsed.inputs.map((input) => ({ + hash: reverseHex(input.previousOutput.txid), + index: input.previousOutput.vout, + sequence: input.sequence, + })); + + const psbtInputs: PsbtInput[] = parsed.inputs.map((input, i) => { + const data = psbtInputData[i]; + const result: PsbtInput = { + type: toFixtureType(input.scriptType), + sighashType: input.scriptType.startsWith("p2tr") ? 0 : 1, + }; + if (data.witnessUtxo) { + result.witnessUtxo = { + value: data.witnessUtxo.value.toString(), + script: Buffer.from(data.witnessUtxo.script).toString("hex"), + }; + } + if (data.bip32Derivation.length > 0) { + result.bip32Derivation = data.bip32Derivation.map(toBip32Derivation); + } + if (data.tapBip32Derivation.length > 0) { + result.tapBip32Derivation = data.tapBip32Derivation.map(toBip32Derivation); + } + return result; + }); + + const outputs: Output[] = psbtOutputData.map((out) => ({ + script: Buffer.from(out.script).toString("hex"), + value: out.value.toString(), + })); + + const psbtOutputs: PsbtOutput[] = psbtOutputData.map((out) => { + const result: PsbtOutput = {}; + if (out.bip32Derivation.length > 0) { + result.bip32Derivation = out.bip32Derivation.map(toBip32Derivation); + } + if (out.tapBip32Derivation.length > 0) { + result.tapBip32Derivation = out.tapBip32Derivation.map(toBip32Derivation); + } + return result; + }); + + return { + walletKeys: xprivs.map((k) => k.toBase58()) as [string, string, string], + psbtBase64: Buffer.from(psbt.serialize()).toString("base64"), + psbtBase64Finalized: null, + inputs, + psbtInputs, + psbtInputsFinalized: null, + outputs, + psbtOutputs, + extractedTransaction: null, + }; +} + +export function generateAllStates( + network: CoinName, + txFormat: TxFormat = "psbt-lite", +): Record { + const unsignedAcid = AcidTest.withConfig(network, "unsigned", txFormat); + const halfsignedAcid = AcidTest.withConfig(network, "halfsigned", txFormat); + const fullsignedAcid = AcidTest.withConfig(network, "fullsigned", txFormat); + + const unsignedPsbt = unsignedAcid.createPsbt(); + const halfsignedPsbt = halfsignedAcid.createPsbt(); + const fullsignedPsbt = fullsignedAcid.createPsbt(); + + const unsigned = snapshotFixture(unsignedAcid, unsignedPsbt); + const halfsigned = snapshotFixture(halfsignedAcid, halfsignedPsbt); + const fullsigned = snapshotFixture(fullsignedAcid, fullsignedPsbt); + + // Finalize the fullsigned PSBT and capture finalized data + fullsignedPsbt.finalizeAllInputs(); + fullsigned.psbtBase64Finalized = Buffer.from(fullsignedPsbt.serialize()).toString("base64"); + const tx = fullsignedPsbt.extractTransaction(); + fullsigned.extractedTransaction = Buffer.from(tx.toBytes()).toString("hex"); + + return { unsigned, halfsigned, fullsigned }; +} diff --git a/packages/wasm-utxo/test/fixedScript/musig2Nonces.ts b/packages/wasm-utxo/test/fixedScript/musig2Nonces.ts index 156bae19..a3cd0486 100644 --- a/packages/wasm-utxo/test/fixedScript/musig2Nonces.ts +++ b/packages/wasm-utxo/test/fixedScript/musig2Nonces.ts @@ -4,14 +4,14 @@ import { loadPsbtFixture, getBitGoPsbt, type Fixture } from "./fixtureUtil.js"; describe("MuSig2 nonce management", function () { describe("Bitcoin mainnet", function () { - const networkName = "bitcoin"; + const networkName = "btc"; let fixture: Fixture; let userKey: BIP32; let backupKey: BIP32; let bitgoKey: BIP32; - before(function () { - fixture = loadPsbtFixture(networkName, "unsigned"); + before(async function () { + fixture = await loadPsbtFixture(networkName, "unsigned"); userKey = BIP32.fromBase58(fixture.walletKeys[0]); backupKey = BIP32.fromBase58(fixture.walletKeys[1]); bitgoKey = BIP32.fromBase58(fixture.walletKeys[2]); @@ -93,7 +93,7 @@ describe("MuSig2 nonce management", function () { }); it("should reject custom session ID on mainnet (security)", function () { - const unsignedBitgoPsbt = getBitGoPsbt(fixture, "bitcoin"); + const unsignedBitgoPsbt = getBitGoPsbt(fixture, "btc"); // Custom session ID should be rejected on mainnet for security const customSessionId = new Uint8Array(32).fill(1); diff --git a/packages/wasm-utxo/test/fixedScript/networkSupport.util.ts b/packages/wasm-utxo/test/fixedScript/networkSupport.util.ts index 030e63c0..6bdafb44 100644 --- a/packages/wasm-utxo/test/fixedScript/networkSupport.util.ts +++ b/packages/wasm-utxo/test/fixedScript/networkSupport.util.ts @@ -1,15 +1,3 @@ -import * as utxolib from "@bitgo/utxo-lib"; +import { coinNames, isMainnet, type CoinName } from "../../js/coinName.js"; -/** - * Get networks that have psbt fixtures - */ -export function getFixtureNetworks(): utxolib.Network[] { - return utxolib.getNetworkList().filter((network) => { - return ( - // we only have fixtures for mainnet networks - utxolib.isMainnet(network) && - // we don't have fixtures for bitcoinsv since it is not really supported any longer - network !== utxolib.networks.bitcoinsv - ); - }); -} +export const mainnetCoinNames = coinNames.filter((c): c is CoinName => isMainnet(c) && c !== "bsv"); diff --git a/packages/wasm-utxo/test/fixedScript/parseTransactionWithWalletKeys.ts b/packages/wasm-utxo/test/fixedScript/parseTransactionWithWalletKeys.ts index 6e78524d..21f8ab85 100644 --- a/packages/wasm-utxo/test/fixedScript/parseTransactionWithWalletKeys.ts +++ b/packages/wasm-utxo/test/fixedScript/parseTransactionWithWalletKeys.ts @@ -1,5 +1,4 @@ import assert from "node:assert"; -import * as utxolib from "@bitgo/utxo-lib"; import { fixedScriptWallet } from "../../js/index.js"; import { BitGoPsbt, InputScriptType } from "../../js/fixedScriptWallet/index.js"; import type { RootWalletKeys } from "../../js/fixedScriptWallet/RootWalletKeys.js"; @@ -11,7 +10,9 @@ import { loadReplayProtectionKeyFromFixture, type Fixture, } from "./fixtureUtil.js"; -import { getFixtureNetworks } from "./networkSupport.util.js"; +import { mainnetCoinNames } from "./networkSupport.util.js"; +import { createOtherWalletKeys } from "./generateFixture.js"; +import { txFormats } from "../../js/testutils/AcidTest.js"; function getExpectedInputScriptType(fixtureScriptType: string): InputScriptType { // Map fixture types to InputScriptType values @@ -33,266 +34,273 @@ function getExpectedInputScriptType(fixtureScriptType: string): InputScriptType } } -function getOtherWalletKeys(): utxolib.bitgo.RootWalletKeys { - const otherWalletKeys = utxolib.testutil.getKeyTriple("too many secrets"); - return new utxolib.bitgo.RootWalletKeys(otherWalletKeys); -} - describe("parseTransactionWithWalletKeys", function () { - getFixtureNetworks().forEach((network) => { - const networkName = utxolib.getNetworkName(network); - - describe(`network: ${networkName}`, function () { - let fullsignedPsbtBytes: Buffer; - let bitgoPsbt: BitGoPsbt; - let rootWalletKeys: RootWalletKeys; - let replayProtectionKey: ECPair; - let fixture: Fixture; - - before(function () { - fixture = loadPsbtFixture(networkName, "fullsigned"); - fullsignedPsbtBytes = getPsbtBuffer(fixture); - bitgoPsbt = fixedScriptWallet.BitGoPsbt.fromBytes(fullsignedPsbtBytes, networkName); - rootWalletKeys = loadWalletKeysFromFixture(fixture); - replayProtectionKey = loadReplayProtectionKeyFromFixture(fixture); - }); - - it("should have matching unsigned transaction ID", function () { - const unsignedTxId = bitgoPsbt.unsignedTxId(); - const expectedUnsignedTxid = utxolib.bitgo - .createPsbtFromBuffer(fullsignedPsbtBytes, network) - .getUnsignedTx() - .getId(); - assert.strictEqual(unsignedTxId, expectedUnsignedTxid); - }); + mainnetCoinNames.forEach((networkName) => { + txFormats + .filter((f) => f !== "psbt" || networkName !== "zec") + .forEach((txFormat) => { + describe(`${networkName} ${txFormat}`, function () { + let fullsignedPsbtBytes: Buffer; + let bitgoPsbt: BitGoPsbt; + let rootWalletKeys: RootWalletKeys; + let replayProtectionKey: ECPair; + let fixture: Fixture; + + before(async function () { + fixture = await loadPsbtFixture(networkName, "fullsigned", txFormat); + fullsignedPsbtBytes = getPsbtBuffer(fixture); + bitgoPsbt = fixedScriptWallet.BitGoPsbt.fromBytes(fullsignedPsbtBytes, networkName); + rootWalletKeys = loadWalletKeysFromFixture(fixture); + replayProtectionKey = loadReplayProtectionKeyFromFixture(fixture); + }); + + it("should have valid unsigned transaction ID format", function () { + const unsignedTxId = bitgoPsbt.unsignedTxId(); + assert.strictEqual(unsignedTxId.length, 64, "unsignedTxId should be 64 chars"); + assert.match(unsignedTxId, /^[0-9a-f]{64}$/, "unsignedTxId should be lowercase hex"); + }); + + it("should parse transaction and identify internal/external outputs", function () { + const parsed = bitgoPsbt.parseTransactionWithWalletKeys(rootWalletKeys, { + replayProtection: { publicKeys: [replayProtectionKey] }, + }); - it("should parse transaction and identify internal/external outputs", function () { - const parsed = bitgoPsbt.parseTransactionWithWalletKeys(rootWalletKeys, { - replayProtection: { publicKeys: [replayProtectionKey] }, - }); + // Verify all inputs have addresses and values + parsed.inputs.forEach((input, i) => { + // Verify previousOutput structure + assert.ok(input.previousOutput, `Input ${i} should have previousOutput`); + assert.ok( + typeof input.previousOutput === "object", + `Input ${i} previousOutput should be an object`, + ); + assert.ok( + typeof input.previousOutput.txid === "string", + `Input ${i} previousOutput.txid should be string`, + ); + assert.strictEqual( + input.previousOutput.txid.length, + 64, + `Input ${i} previousOutput.txid should be 64 chars (32 bytes hex)`, + ); + assert.ok( + typeof input.previousOutput.vout === "number", + `Input ${i} previousOutput.vout should be number`, + ); + assert.ok( + input.previousOutput.vout >= 0, + `Input ${i} previousOutput.vout should be >= 0`, + ); + + // Verify address + assert.ok(input.address, `Input ${i} should have an address`); + assert.ok(typeof input.address === "string", `Input ${i} address should be string`); + + // Verify value + assert.ok(typeof input.value === "bigint", `Input ${i} value should be bigint`); + assert.ok(input.value > 0n, `Input ${i} value should be > 0`); + + // Verify scriptId structure (can be null for replay protection inputs) + if (input.scriptId !== null) { + assert.ok( + typeof input.scriptId === "object", + `Input ${i} scriptId should be an object when present`, + ); + assert.ok( + typeof input.scriptId.chain === "number", + `Input ${i} scriptId.chain should be number`, + ); + assert.ok( + typeof input.scriptId.index === "number", + `Input ${i} scriptId.index should be number`, + ); + assert.ok(input.scriptId.chain >= 0, `Input ${i} scriptId.chain should be >= 0`); + assert.ok(input.scriptId.index >= 0, `Input ${i} scriptId.index should be >= 0`); + } + + // Verify scriptType is present + assert.ok(input.scriptType, `Input ${i} should have scriptType`); + assert.ok( + typeof input.scriptType === "string", + `Input ${i} scriptType should be string`, + ); + }); - // Verify all inputs have addresses and values - parsed.inputs.forEach((input, i) => { - // Verify previousOutput structure - assert.ok(input.previousOutput, `Input ${i} should have previousOutput`); - assert.ok( - typeof input.previousOutput === "object", - `Input ${i} previousOutput should be an object`, - ); - assert.ok( - typeof input.previousOutput.txid === "string", - `Input ${i} previousOutput.txid should be string`, - ); - assert.strictEqual( - input.previousOutput.txid.length, - 64, - `Input ${i} previousOutput.txid should be 64 chars (32 bytes hex)`, - ); - assert.ok( - typeof input.previousOutput.vout === "number", - `Input ${i} previousOutput.vout should be number`, - ); - assert.ok( - input.previousOutput.vout >= 0, - `Input ${i} previousOutput.vout should be >= 0`, - ); - - // Verify address - assert.ok(input.address, `Input ${i} should have an address`); - assert.ok(typeof input.address === "string", `Input ${i} address should be string`); - - // Verify value - assert.ok(typeof input.value === "bigint", `Input ${i} value should be bigint`); - assert.ok(input.value > 0n, `Input ${i} value should be > 0`); - - // Verify scriptId structure (can be null for replay protection inputs) - if (input.scriptId !== null) { - assert.ok( - typeof input.scriptId === "object", - `Input ${i} scriptId should be an object when present`, + // Validate outputs + assert.ok(parsed.outputs.length > 0, "Should have at least one output"); + + // Count internal outputs (scriptId is defined and not null) + const internalOutputs = parsed.outputs.filter((o) => o.scriptId); + + // Count external outputs (scriptId is null or undefined) + const externalOutputs = parsed.outputs.filter((o) => o.scriptId === null); + + assert.ok(externalOutputs.every((o) => o.address || o.script)); + const nonAddressOutputs = externalOutputs.filter((o) => o.address === null); + assert.strictEqual(nonAddressOutputs.length, 1); + const [opReturnOutput] = nonAddressOutputs; + const opReturnData = Buffer.from("setec astronomy"); + const expectedOpReturn = Buffer.concat([ + Buffer.from([0x6a, opReturnData.length]), + opReturnData, + ]); + assert.strictEqual( + Buffer.from(opReturnOutput.script).toString("hex"), + expectedOpReturn.toString("hex"), ); - assert.ok( - typeof input.scriptId.chain === "number", - `Input ${i} scriptId.chain should be number`, - ); - assert.ok( - typeof input.scriptId.index === "number", - `Input ${i} scriptId.index should be number`, + + // Fixtures now have 3 external outputs + assert.ok(internalOutputs.length > 0, "Should have internal outputs (have scriptId)"); + assert.strictEqual( + externalOutputs.length, + 3, + "Should have 3 external outputs in test fixture", ); - assert.ok(input.scriptId.chain >= 0, `Input ${i} scriptId.chain should be >= 0`); - assert.ok(input.scriptId.index >= 0, `Input ${i} scriptId.index should be >= 0`); - } - // Verify scriptType is present - assert.ok(input.scriptType, `Input ${i} should have scriptType`); - assert.ok(typeof input.scriptType === "string", `Input ${i} scriptType should be string`); - }); + // Verify all outputs have proper structure + parsed.outputs.forEach((output, i) => { + assert.ok( + output.script instanceof Uint8Array, + `Output ${i} script should be Uint8Array`, + ); + assert.ok(typeof output.value === "bigint", `Output ${i} value should be bigint`); + if (output.address === null) { + // OP_RETURN outputs have no address and value should be 0 + assert.ok( + output.script[0] === 0x6a, + `Output ${i} script should start with OP_RETURN`, + ); + assert.ok( + output.value === 0n, + `Output ${i} value should be 0 if address is undefined`, + ); + } else { + assert.ok(output.value > 0n, `Output ${i} value should be > 0`); + } + }); - // Validate outputs - assert.ok(parsed.outputs.length > 0, "Should have at least one output"); - - // Count internal outputs (scriptId is defined and not null) - const internalOutputs = parsed.outputs.filter((o) => o.scriptId); - - // Count external outputs (scriptId is null or undefined) - const externalOutputs = parsed.outputs.filter((o) => o.scriptId === null); - - assert.ok(externalOutputs.every((o) => o.address || o.script)); - const nonAddressOutputs = externalOutputs.filter((o) => o.address === null); - assert.strictEqual(nonAddressOutputs.length, 1); - const [opReturnOutput] = nonAddressOutputs; - const expectedOpReturn = utxolib.payments.embed({ - data: [Buffer.from("setec astronomy")], - }).output; - assert.strictEqual( - Buffer.from(opReturnOutput.script).toString("hex"), - expectedOpReturn.toString("hex"), - ); - - // Fixtures now have 3 external outputs - assert.ok(internalOutputs.length > 0, "Should have internal outputs (have scriptId)"); - assert.strictEqual( - externalOutputs.length, - 3, - "Should have 3 external outputs in test fixture", - ); - - // Verify all outputs have proper structure - parsed.outputs.forEach((output, i) => { - assert.ok(output.script instanceof Uint8Array, `Output ${i} script should be Uint8Array`); - assert.ok(typeof output.value === "bigint", `Output ${i} value should be bigint`); - if (output.address === null) { - // OP_RETURN outputs have no address and value should be 0 - assert.ok(output.script[0] === 0x6a, `Output ${i} script should start with OP_RETURN`); - assert.ok(output.value === 0n, `Output ${i} value should be 0 if address is undefined`); - } else { - assert.ok(output.value > 0n, `Output ${i} value should be > 0`); - } - }); + // Verify spend amount (should be > 0 since there are external outputs) + // AcidTest uses other wallet (800) + null wallet (700) = 1500 + assert.strictEqual(parsed.spendAmount, 800n + 700n); + + // Verify miner fee calculation + const totalInputValue = parsed.inputs.reduce((sum, i) => sum + i.value, 0n); + const totalOutputValue = parsed.outputs.reduce((sum, o) => sum + o.value, 0n); + assert.strictEqual( + parsed.minerFee, + totalInputValue - totalOutputValue, + "Miner fee should equal inputs minus outputs", + ); + assert.ok(parsed.minerFee > 0n, "Miner fee should be > 0"); - // Verify spend amount (should be > 0 since there are external outputs) - assert.strictEqual(parsed.spendAmount, 900n * 2n); - - // Verify miner fee calculation - const totalInputValue = parsed.inputs.reduce((sum, i) => sum + i.value, 0n); - const totalOutputValue = parsed.outputs.reduce((sum, o) => sum + o.value, 0n); - assert.strictEqual( - parsed.minerFee, - totalInputValue - totalOutputValue, - "Miner fee should equal inputs minus outputs", - ); - assert.ok(parsed.minerFee > 0n, "Miner fee should be > 0"); - - // Verify virtual size - assert.ok(typeof parsed.virtualSize === "number", "Virtual size should be a number"); - assert.ok(parsed.virtualSize > 0, "Virtual size should be > 0"); - }); + // Verify virtual size + assert.ok(typeof parsed.virtualSize === "number", "Virtual size should be a number"); + assert.ok(parsed.virtualSize > 0, "Virtual size should be > 0"); + }); - it("should parse inputs with correct scriptType", function () { - const parsed = bitgoPsbt.parseTransactionWithWalletKeys(rootWalletKeys, { - replayProtection: { publicKeys: [replayProtectionKey] }, - }); + it("should parse inputs with correct scriptType", function () { + const parsed = bitgoPsbt.parseTransactionWithWalletKeys(rootWalletKeys, { + replayProtection: { publicKeys: [replayProtectionKey] }, + }); - // Verify all inputs have scriptType matching fixture - parsed.inputs.forEach((input, i) => { - const fixtureInput = fixture.psbtInputs[i]; - const expectedScriptType = getExpectedInputScriptType(fixtureInput.type); - assert.strictEqual( - input.scriptType, - expectedScriptType, - `Input ${i} scriptType should be ${expectedScriptType}, got ${input.scriptType}`, - ); - - // Verify previousOutput is present and structured correctly - assert.ok(input.previousOutput, `Input ${i} should have previousOutput`); - assert.ok( - typeof input.previousOutput === "object", - `Input ${i} previousOutput should be an object`, - ); - assert.ok( - typeof input.previousOutput.txid === "string", - `Input ${i} previousOutput.txid should be string`, - ); - assert.strictEqual( - input.previousOutput.txid.length, - 64, - `Input ${i} previousOutput.txid should be 64 chars`, - ); - assert.ok( - typeof input.previousOutput.vout === "number", - `Input ${i} previousOutput.vout should be number`, - ); - - // Verify scriptId structure when present (can be null for replay protection inputs) - if (input.scriptId !== null) { - assert.ok( - typeof input.scriptId === "object", - `Input ${i} scriptId should be an object when present`, - ); - assert.ok( - typeof input.scriptId.chain === "number", - `Input ${i} scriptId.chain should be number`, + // Verify all inputs have scriptType matching fixture + parsed.inputs.forEach((input, i) => { + const fixtureInput = fixture.psbtInputs[i]; + const expectedScriptType = getExpectedInputScriptType(fixtureInput.type); + assert.strictEqual( + input.scriptType, + expectedScriptType, + `Input ${i} scriptType should be ${expectedScriptType}, got ${input.scriptType}`, + ); + + // Verify previousOutput is present and structured correctly + assert.ok(input.previousOutput, `Input ${i} should have previousOutput`); + assert.ok( + typeof input.previousOutput === "object", + `Input ${i} previousOutput should be an object`, + ); + assert.ok( + typeof input.previousOutput.txid === "string", + `Input ${i} previousOutput.txid should be string`, + ); + assert.strictEqual( + input.previousOutput.txid.length, + 64, + `Input ${i} previousOutput.txid should be 64 chars`, + ); + assert.ok( + typeof input.previousOutput.vout === "number", + `Input ${i} previousOutput.vout should be number`, + ); + + // Verify scriptId structure when present (can be null for replay protection inputs) + if (input.scriptId !== null) { + assert.ok( + typeof input.scriptId === "object", + `Input ${i} scriptId should be an object when present`, + ); + assert.ok( + typeof input.scriptId.chain === "number", + `Input ${i} scriptId.chain should be number`, + ); + assert.ok( + typeof input.scriptId.index === "number", + `Input ${i} scriptId.index should be number`, + ); + } + }); + }); + + it("should fail to parse with other wallet keys", function () { + assert.throws( + () => { + bitgoPsbt.parseTransactionWithWalletKeys(createOtherWalletKeys(), { + replayProtection: { publicKeys: [replayProtectionKey] }, + }); + }, + (error: Error) => { + return error.message.includes("wallet validation failed"); + }, ); - assert.ok( - typeof input.scriptId.index === "number", - `Input ${i} scriptId.index should be number`, + }); + + it("should recognize output for other wallet keys", function () { + const parsedOutputs = bitgoPsbt.parseOutputsWithWalletKeys(createOtherWalletKeys()); + + // Should return an array of parsed outputs + assert.ok(Array.isArray(parsedOutputs), "Should return an array"); + + // Compare with the original wallet keys to verify we get different results + const originalParsedOutputs = bitgoPsbt.parseOutputsWithWalletKeys(rootWalletKeys); + + // Should have the same number of outputs + assert.strictEqual( + parsedOutputs.length, + originalParsedOutputs.length, + "Should parse the same number of outputs", ); - } - }); - }); - it("should fail to parse with other wallet keys", function () { - assert.throws( - () => { - bitgoPsbt.parseTransactionWithWalletKeys(getOtherWalletKeys(), { - replayProtection: { publicKeys: [replayProtectionKey] }, - }); - }, - (error: Error) => { - return error.message.includes( - "Failed to parse transaction: Input 0: wallet validation failed", + // Find outputs that belong to the other wallet keys (scriptId !== null) + const otherWalletOutputs = parsedOutputs.filter((o) => o.scriptId !== null); + + // Should have exactly one output for the other wallet keys + assert.strictEqual( + otherWalletOutputs.length, + 1, + "Should have exactly one output belonging to the other wallet keys", ); - }, - ); - }); - it("should recognize output for other wallet keys", function () { - const parsedOutputs = bitgoPsbt.parseOutputsWithWalletKeys(getOtherWalletKeys()); - - // Should return an array of parsed outputs - assert.ok(Array.isArray(parsedOutputs), "Should return an array"); - - // Compare with the original wallet keys to verify we get different results - const originalParsedOutputs = bitgoPsbt.parseOutputsWithWalletKeys(rootWalletKeys); - - // Should have the same number of outputs - assert.strictEqual( - parsedOutputs.length, - originalParsedOutputs.length, - "Should parse the same number of outputs", - ); - - // Find outputs that belong to the other wallet keys (scriptId !== null) - const otherWalletOutputs = parsedOutputs.filter((o) => o.scriptId !== null); - - // Should have exactly one output for the other wallet keys - assert.strictEqual( - otherWalletOutputs.length, - 1, - "Should have exactly one output belonging to the other wallet keys", - ); - - // Verify that this output is marked as external (scriptId === null) under regular wallet keys - const otherWalletOutputIndex = parsedOutputs.findIndex((o) => o.scriptId !== null); - const sameOutputWithRegularKeys = originalParsedOutputs[otherWalletOutputIndex]; - - assert.strictEqual( - sameOutputWithRegularKeys.scriptId, - null, - "The output belonging to other wallet keys should be marked as external (scriptId === null) when parsed with regular wallet keys", - ); + // Verify that this output is marked as external (scriptId === null) under regular wallet keys + const otherWalletOutputIndex = parsedOutputs.findIndex((o) => o.scriptId !== null); + const sameOutputWithRegularKeys = originalParsedOutputs[otherWalletOutputIndex]; + + assert.strictEqual( + sameOutputWithRegularKeys.scriptId, + null, + "The output belonging to other wallet keys should be marked as external (scriptId === null) when parsed with regular wallet keys", + ); + }); + }); }); - }); }); describe("error handling", function () { @@ -300,7 +308,7 @@ describe("parseTransactionWithWalletKeys", function () { const invalidBytes = new Uint8Array([0x00, 0x01, 0x02]); assert.throws( () => { - fixedScriptWallet.BitGoPsbt.fromBytes(invalidBytes, "bitcoin"); + fixedScriptWallet.BitGoPsbt.fromBytes(invalidBytes, "btc"); }, (error: Error) => { return error.message.includes("Failed to deserialize PSBT"); diff --git a/packages/wasm-utxo/test/fixedScript/psbtReconstruction.ts b/packages/wasm-utxo/test/fixedScript/psbtReconstruction.ts index ef3f2f55..2a2ffcc9 100644 --- a/packages/wasm-utxo/test/fixedScript/psbtReconstruction.ts +++ b/packages/wasm-utxo/test/fixedScript/psbtReconstruction.ts @@ -1,5 +1,4 @@ import assert from "node:assert"; -import * as utxolib from "@bitgo/utxo-lib"; import { fixedScriptWallet } from "../../js/index.js"; import { BitGoPsbt, @@ -15,7 +14,8 @@ import { getPsbtBuffer, type Fixture, } from "./fixtureUtil.js"; -import { getFixtureNetworks } from "./networkSupport.util.js"; +import { mainnetCoinNames } from "./networkSupport.util.js"; +import { createOtherWalletKeys } from "./generateFixture.js"; // Zcash Sapling consensus branch ID for test fixtures const ZCASH_SAPLING_BRANCH_ID = 0x76b809bb; @@ -36,23 +36,6 @@ function getSignPathFromScriptType(scriptType: InputScriptType): SignPath | unde } } -/** - * Get "other wallet keys" for testing outputs from different wallet - * Uses the same seed as utxo-lib tests: "too many secrets" - */ -function getOtherWalletKeys(): RootWalletKeys { - const otherWalletKeys = utxolib.testutil.getKeyTriple("too many secrets"); - const neuteredKeys = otherWalletKeys.map((key) => key.neutered()) as [ - utxolib.BIP32Interface, - utxolib.BIP32Interface, - utxolib.BIP32Interface, - ]; - return fixedScriptWallet.RootWalletKeys.from({ - triple: neuteredKeys, - derivationPrefixes: ["0/0", "0/0", "0/0"], - }); -} - /** * Reverse a hex string by bytes (for txid conversion) * Bitcoin txids in fixtures are in internal byte order (reversed) @@ -62,20 +45,18 @@ function reverseHex(hex: string): string { } describe("PSBT reconstruction", function () { - getFixtureNetworks().forEach((network) => { - const networkName = utxolib.getNetworkName(network); - + mainnetCoinNames.forEach((networkName) => { describe(`network: ${networkName}`, function () { let fixture: Fixture; let originalPsbt: BitGoPsbt; let rootWalletKeys: RootWalletKeys; let otherWalletKeys: RootWalletKeys; - before(function () { - fixture = loadPsbtFixture(networkName, "unsigned"); + before(async function () { + fixture = await loadPsbtFixture(networkName, "unsigned"); originalPsbt = fixedScriptWallet.BitGoPsbt.fromBytes(getPsbtBuffer(fixture), networkName); rootWalletKeys = loadWalletKeysFromFixture(fixture); - otherWalletKeys = getOtherWalletKeys(); + otherWalletKeys = createOtherWalletKeys(); }); it("should reconstruct PSBT from parsed data with matching unsigned txid", function () { @@ -90,7 +71,7 @@ describe("PSBT reconstruction", function () { // Create empty PSBT with same version/locktime let reconstructed: BitGoPsbt; - if (networkName === "zcash" || networkName === "zcashTest") { + if (networkName === "zec" || networkName === "tzec") { const zcashPsbt = ZcashBitGoPsbt.fromBytes(getPsbtBuffer(fixture), networkName); reconstructed = ZcashBitGoPsbt.createEmptyWithConsensusBranchId( networkName, @@ -193,7 +174,7 @@ describe("PSBT reconstruction", function () { assert.strictEqual(typeof originalPsbt.version(), "number", "version should be a number"); assert.strictEqual(typeof originalPsbt.lockTime(), "number", "lockTime should be a number"); // Version depends on network: Zcash uses version 4 (Sapling) or 5 (NU5), others use 1 or 2 - if (network === utxolib.networks.zcash) { + if (networkName === "zec") { assert.ok( originalPsbt.version() === 4 || originalPsbt.version() === 5, `Zcash version should be 4 or 5, got ${originalPsbt.version()}`, @@ -235,7 +216,7 @@ describe("PSBT reconstruction", function () { it("should create equivalent PSBTs using block height vs explicit branch ID (Zcash only)", function () { // Skip for non-Zcash networks - if (networkName !== "zcash" && networkName !== "zcashTest") { + if (networkName !== "zec" && networkName !== "tzec") { this.skip(); } @@ -249,7 +230,7 @@ describe("PSBT reconstruction", function () { const zcashPsbt = ZcashBitGoPsbt.fromBytes(getPsbtBuffer(fixture), networkName); // Sapling activation heights: mainnet=419200, testnet=280000 - const saplingHeight = networkName === "zcash" ? 419200 : 280000; + const saplingHeight = networkName === "zec" ? 419200 : 280000; // Create PSBT using explicit branch ID (advanced approach) const psbtWithBranchId = ZcashBitGoPsbt.createEmptyWithConsensusBranchId( @@ -350,9 +331,9 @@ describe("PSBT reconstruction", function () { ); }); - it("should extract transaction with valid getId() after finalization", function () { + it("should extract transaction with valid getId() after finalization", async function () { // Load fullsigned fixture for this network - const fullsignedFixture = loadPsbtFixture(networkName, "fullsigned"); + const fullsignedFixture = await loadPsbtFixture(networkName, "fullsigned"); const psbt = fixedScriptWallet.BitGoPsbt.fromBytes( getPsbtBuffer(fullsignedFixture), networkName, diff --git a/packages/wasm-utxo/test/fixedScript/signAndVerifySignature.ts b/packages/wasm-utxo/test/fixedScript/signAndVerifySignature.ts index 1820c8eb..9838486d 100644 --- a/packages/wasm-utxo/test/fixedScript/signAndVerifySignature.ts +++ b/packages/wasm-utxo/test/fixedScript/signAndVerifySignature.ts @@ -1,12 +1,7 @@ import assert from "node:assert"; -import * as utxolib from "@bitgo/utxo-lib"; import { BIP32, ECPair } from "../../js/index.js"; -import { - BitGoPsbt, - RootWalletKeys, - ParsedTransaction, - type NetworkName, -} from "../../js/fixedScriptWallet/index.js"; +import { BitGoPsbt, RootWalletKeys, ParsedTransaction } from "../../js/fixedScriptWallet/index.js"; +import type { CoinName } from "../../js/coinName.js"; import { loadPsbtFixture, loadWalletKeysFromFixture, @@ -14,7 +9,8 @@ import { type Fixture, loadReplayProtectionKeyFromFixture, } from "./fixtureUtil.js"; -import { getFixtureNetworks } from "./networkSupport.util.js"; +import { mainnetCoinNames } from "./networkSupport.util.js"; +import { txFormats } from "../../js/testutils/AcidTest.js"; type SignatureStage = "unsigned" | "halfsigned" | "fullsigned"; @@ -224,7 +220,7 @@ function signAllInputs( */ function runTestsForFixture( fixture: Fixture, - networkName: NetworkName, + networkName: CoinName, rootWalletKeys: RootWalletKeys, replayProtectionKey: ECPair, xprivs: RootWalletXprivs, @@ -243,161 +239,165 @@ function runTestsForFixture( } describe("verifySignature", function () { - getFixtureNetworks().forEach((network) => { - const networkName = utxolib.getNetworkName(network); - - describe(`network: ${networkName}`, function () { - let rootWalletKeys: RootWalletKeys; - let replayProtectionKey: ECPair; - let xprivs: RootWalletXprivs; - let unsignedFixture: Fixture; - let halfsignedFixture: Fixture; - let fullsignedFixture: Fixture; - - before(function () { - unsignedFixture = loadPsbtFixture(networkName, "unsigned"); - halfsignedFixture = loadPsbtFixture(networkName, "halfsigned"); - fullsignedFixture = loadPsbtFixture(networkName, "fullsigned"); - rootWalletKeys = loadWalletKeysFromFixture(fullsignedFixture); - replayProtectionKey = loadReplayProtectionKeyFromFixture(fullsignedFixture); - xprivs = loadXprivsFromFixture(fullsignedFixture); - }); - - describe("unsigned PSBT", function () { - it("should return false for unsigned inputs, then sign and verify", function () { - runTestsForFixture( - unsignedFixture, - networkName, - rootWalletKeys, - replayProtectionKey, - xprivs, - "unsigned", - ); - }); - }); - - describe("half-signed PSBT", function () { - it("should return true for signed xpubs and false for unsigned, then sign and verify", function () { - runTestsForFixture( - halfsignedFixture, - networkName, - rootWalletKeys, - replayProtectionKey, - xprivs, - "halfsigned", - ); - }); - }); - - describe("fully signed PSBT", function () { - it("should have 2 signatures (2-of-3 multisig)", function () { - runTestsForFixture( - fullsignedFixture, - networkName, - rootWalletKeys, - replayProtectionKey, - xprivs, - "fullsigned", - ); + mainnetCoinNames.forEach((networkName) => { + txFormats + .filter((f) => f !== "psbt" || networkName !== "zec") + .forEach((txFormat) => { + describe(`${networkName} ${txFormat}`, function () { + let rootWalletKeys: RootWalletKeys; + let replayProtectionKey: ECPair; + let xprivs: RootWalletXprivs; + let unsignedFixture: Fixture; + let halfsignedFixture: Fixture; + let fullsignedFixture: Fixture; + + before(async function () { + unsignedFixture = await loadPsbtFixture(networkName, "unsigned", txFormat); + halfsignedFixture = await loadPsbtFixture(networkName, "halfsigned", txFormat); + fullsignedFixture = await loadPsbtFixture(networkName, "fullsigned", txFormat); + rootWalletKeys = loadWalletKeysFromFixture(fullsignedFixture); + replayProtectionKey = loadReplayProtectionKeyFromFixture(fullsignedFixture); + xprivs = loadXprivsFromFixture(fullsignedFixture); + }); + + describe("unsigned PSBT", function () { + it("should return false for unsigned inputs, then sign and verify", function () { + runTestsForFixture( + unsignedFixture, + networkName, + rootWalletKeys, + replayProtectionKey, + xprivs, + "unsigned", + ); + }); + }); + + describe("half-signed PSBT", function () { + it("should return true for signed xpubs and false for unsigned, then sign and verify", function () { + runTestsForFixture( + halfsignedFixture, + networkName, + rootWalletKeys, + replayProtectionKey, + xprivs, + "halfsigned", + ); + }); + }); + + describe("fully signed PSBT", function () { + it("should have 2 signatures (2-of-3 multisig)", function () { + runTestsForFixture( + fullsignedFixture, + networkName, + rootWalletKeys, + replayProtectionKey, + xprivs, + "fullsigned", + ); + }); + }); + + describe("error handling", function () { + it("should throw error for out of bounds input index", function () { + const psbt = getBitGoPsbt(fullsignedFixture, networkName); + assert.throws( + () => { + psbt.verifySignature(999, rootWalletKeys.userKey()); + }, + (error: Error) => { + return error.message.includes("Input index 999 out of bounds"); + }, + "Should throw error for out of bounds input index", + ); + }); + + it("should throw error for invalid xpub", function () { + const psbt = getBitGoPsbt(fullsignedFixture, networkName); + assert.throws( + () => { + psbt.verifySignature(0, "invalid-xpub"); + }, + (error: Error) => { + return error.message.includes("Invalid"); + }, + "Should throw error for invalid xpub", + ); + }); + + it("should return false for xpub not in derivation path", function () { + const psbt = getBitGoPsbt(fullsignedFixture, networkName); + // Create a different xpub that's not in the wallet + // Use a proper 32-byte seed (256 bits) + const differentSeed = Buffer.alloc(32, 0xaa); // 32 bytes filled with 0xaa + const differentKey = BIP32.fromSeed(differentSeed); + const differentXpub = differentKey.neutered(); + + const result = psbt.verifySignature(0, differentXpub); + assert.strictEqual( + result, + false, + "Should return false for xpub not in PSBT derivation paths", + ); + }); + + it("should verify signature with raw public key (Uint8Array)", function () { + const psbt = getBitGoPsbt(fullsignedFixture, networkName); + // Find first wallet input (non-p2shP2pk) for xpub verification + const walletInputIndex = fullsignedFixture.psbtInputs.findIndex( + (input) => input.type !== "p2shP2pk", + ); + assert.ok(walletInputIndex >= 0, "Should have a wallet input"); + + // Verify that xpub-based verification works + const userKey = rootWalletKeys.userKey(); + const hasXpubSig = psbt.verifySignature(walletInputIndex, userKey); + + // Use a random public key that's not in the PSBT to test the API works + const randomSeed = Buffer.alloc(32, 0xcc); + const randomKey = BIP32.fromSeed(randomSeed); + const randomPubkey = randomKey.publicKey; + + // This should return false (no signature for this key) + const result = psbt.verifySignature(walletInputIndex, randomPubkey); + assert.strictEqual(result, false, "Should return false for public key not in PSBT"); + + // Verify the xpub check still works (regression test) + assert.strictEqual(hasXpubSig, true, "Should still verify with xpub"); + }); + + it("should return false for raw public key with no signature", function () { + const psbt = getBitGoPsbt(fullsignedFixture, networkName); + // Create a random public key that's not in the PSBT + const randomSeed = Buffer.alloc(32, 0xbb); + const randomKey = BIP32.fromSeed(randomSeed); + const randomPubkey = randomKey.publicKey; + + const result = psbt.verifySignature(0, randomPubkey); + assert.strictEqual( + result, + false, + "Should return false for public key not in PSBT signatures", + ); + }); + + it("should throw error for invalid key length", function () { + const psbt = getBitGoPsbt(fullsignedFixture, networkName); + const invalidKey = Buffer.alloc(31); // Invalid length (should be 32 for private key or 33 for public key) + + assert.throws( + () => { + psbt.verifySignature(0, invalidKey); + }, + (error: Error) => { + return error.message.includes("Invalid key length"); + }, + "Should throw error for invalid key length", + ); + }); + }); }); }); - - describe("error handling", function () { - it("should throw error for out of bounds input index", function () { - const psbt = getBitGoPsbt(fullsignedFixture, networkName); - assert.throws( - () => { - psbt.verifySignature(999, rootWalletKeys.userKey()); - }, - (error: Error) => { - return error.message.includes("Input index 999 out of bounds"); - }, - "Should throw error for out of bounds input index", - ); - }); - - it("should throw error for invalid xpub", function () { - const psbt = getBitGoPsbt(fullsignedFixture, networkName); - assert.throws( - () => { - psbt.verifySignature(0, "invalid-xpub"); - }, - (error: Error) => { - return error.message.includes("Invalid"); - }, - "Should throw error for invalid xpub", - ); - }); - - it("should return false for xpub not in derivation path", function () { - const psbt = getBitGoPsbt(fullsignedFixture, networkName); - // Create a different xpub that's not in the wallet - // Use a proper 32-byte seed (256 bits) - const differentSeed = Buffer.alloc(32, 0xaa); // 32 bytes filled with 0xaa - const differentKey = BIP32.fromSeed(differentSeed); - const differentXpub = differentKey.neutered(); - - const result = psbt.verifySignature(0, differentXpub); - assert.strictEqual( - result, - false, - "Should return false for xpub not in PSBT derivation paths", - ); - }); - - it("should verify signature with raw public key (Uint8Array)", function () { - const psbt = getBitGoPsbt(fullsignedFixture, networkName); - // Verify that xpub-based verification works - const userKey = rootWalletKeys.userKey(); - const hasXpubSig = psbt.verifySignature(0, userKey); - - // This test specifically checks that raw public key verification works - // We test the underlying WASM API by ensuring both xpub and raw pubkey - // calls reach the correct methods - - // Use a random public key that's not in the PSBT to test the API works - const randomSeed = Buffer.alloc(32, 0xcc); - const randomKey = BIP32.fromSeed(randomSeed); - const randomPubkey = randomKey.publicKey; - - // This should return false (no signature for this key) - const result = psbt.verifySignature(0, randomPubkey); - assert.strictEqual(result, false, "Should return false for public key not in PSBT"); - - // Verify the xpub check still works (regression test) - assert.strictEqual(hasXpubSig, true, "Should still verify with xpub"); - }); - - it("should return false for raw public key with no signature", function () { - const psbt = getBitGoPsbt(fullsignedFixture, networkName); - // Create a random public key that's not in the PSBT - const randomSeed = Buffer.alloc(32, 0xbb); - const randomKey = BIP32.fromSeed(randomSeed); - const randomPubkey = randomKey.publicKey; - - const result = psbt.verifySignature(0, randomPubkey); - assert.strictEqual( - result, - false, - "Should return false for public key not in PSBT signatures", - ); - }); - - it("should throw error for invalid key length", function () { - const psbt = getBitGoPsbt(fullsignedFixture, networkName); - const invalidKey = Buffer.alloc(31); // Invalid length (should be 32 for private key or 33 for public key) - - assert.throws( - () => { - psbt.verifySignature(0, invalidKey); - }, - (error: Error) => { - return error.message.includes("Invalid key length"); - }, - "Should throw error for invalid key length", - ); - }); - }); - }); }); }); diff --git a/packages/wasm-utxo/test/fixtures.ts b/packages/wasm-utxo/test/fixtures.ts index d2cbf7d9..85c7fbe0 100644 --- a/packages/wasm-utxo/test/fixtures.ts +++ b/packages/wasm-utxo/test/fixtures.ts @@ -1,7 +1,13 @@ import * as fs from "fs/promises"; -export async function getFixture(path: string, defaultValue: unknown): Promise { + +type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }; + +export async function getFixture( + path: string, + defaultValue: (() => JsonValue) | JsonValue, +): Promise { try { - return JSON.parse(await fs.readFile(path, "utf8")) as unknown; + return JSON.parse(await fs.readFile(path, "utf8")) as JsonValue; } catch (e) { if ( typeof e === "object" && @@ -9,7 +15,8 @@ export async function getFixture(path: string, defaultValue: unknown): Promise)` containing the serialized half-signed transaction bytes + * - `Err(WasmUtxoError)` if validation fails or extraction fails + * + * # Errors + * - Returns error if any input is not a p2ms type (Taproot, replay protection, etc.) + * - Returns error if any input has 0 or more than 1 partial signature + */ + extract_half_signed_legacy_tx(): Uint8Array; + /** + * Extract the final transaction from a finalized PSBT + * + * This method should be called after all inputs have been finalized. + * It extracts the fully signed transaction as a WASM transaction instance + * appropriate for the network (WasmTransaction, WasmDashTransaction, or WasmZcashTransaction). + * + * # Returns + * - `Ok(JsValue)` containing the WASM transaction instance + * - `Err(WasmUtxoError)` if the PSBT is not fully finalized or extraction fails + */ + extract_transaction(): any; + /** + * Extract the final transaction as a WasmZcashTransaction (for Zcash networks) + * + * This avoids re-parsing bytes by returning the transaction directly. + * Only valid for Zcash networks. + */ + extract_zcash_transaction(): WasmZcashTransaction; + /** + * Finalize all inputs in the PSBT + * + * This method attempts to finalize all inputs in the PSBT, computing the final + * scriptSig and witness data for each input. + * + * # Returns + * - `Ok(())` if all inputs were successfully finalized + * - `Err(WasmUtxoError)` if any input failed to finalize + */ + finalize_all_inputs(): void; + /** + * Deserialize a PSBT from bytes with network-specific logic + */ + static from_bytes(bytes: Uint8Array, network: string): BitGoPsbt; + /** + * Generate and store MuSig2 nonces for all MuSig2 inputs + * + * This method generates nonces using the State-Machine API and stores them in the PSBT. + * The nonces are stored as proprietary fields in the PSBT and will be included when serialized. + * After ALL participants have generated their nonces, they can sign MuSig2 inputs using + * sign_with_xpriv(). + * + * # Arguments + * * `xpriv` - The extended private key (xpriv) for signing + * * `session_id_bytes` - Optional 32-byte session ID for nonce generation. **Only allowed on testnets**. + * On mainnets, a secure random session ID is always generated automatically. + * Must be unique per signing session. + * + * # Returns + * Ok(()) if nonces were successfully generated and stored + * + * # Errors + * Returns error if: + * - Nonce generation fails + * - session_id length is invalid + * - Custom session_id is provided on a mainnet (security restriction) + * + * # Security + * The session_id MUST be cryptographically random and unique for each signing session. + * Never reuse a session_id with the same key! On mainnets, session_id is always randomly + * generated for security. Custom session_id is only allowed on testnets for testing purposes. + */ + generate_musig2_nonces(xpriv: WasmBIP32, session_id_bytes?: Uint8Array | null): void; + /** + * Get all PSBT inputs as an array of PsbtInputData + * + * Returns an array with witness_utxo, bip32_derivation, and tap_bip32_derivation + * for each input. + */ + get_inputs(): any; + /** + * Get the network type for transaction extraction + * + * Returns "bitcoin", "dash", or "zcash" to indicate which transaction + * wrapper class should be used in TypeScript. + */ + get_network_type(): string; + /** + * Get all PSBT outputs as an array of PsbtOutputData + * + * Returns an array with script, value, bip32_derivation, and tap_bip32_derivation + * for each output. + */ + get_outputs(): any; + /** + * Get all PSBT outputs with resolved address strings. + * + * Unlike the generic WrapPsbt which requires a coin parameter, BitGoPsbt + * uses the network it was created/deserialized with to resolve addresses. + */ + get_outputs_with_address(): any; + /** + * Get the number of inputs in the PSBT + */ + input_count(): number; + /** + * Check if an input is a MuSig2 keypath input. + * + * MuSig2 inputs require special handling: nonces must be generated first with + * `generate_musig2_nonces()`, then signed with `sign_musig2_input()`. + * + * # Arguments + * - `input_index`: The index of the input to check (0-based) + * + * # Returns + * - `true` if the input is a MuSig2 keypath input + * - `false` otherwise (or if input_index is out of bounds) + */ + is_musig2_input(input_index: number): boolean; + /** + * Get the transaction lock time + */ + lock_time(): number; + /** + * Get the network of the PSBT + */ + network(): string; + /** + * Get the number of outputs in the PSBT + */ + output_count(): number; + /** + * Parse outputs with wallet keys to identify which outputs belong to a wallet + * + * Note: This method does NOT validate wallet inputs. It only parses outputs. + */ + parse_outputs_with_wallet_keys(wallet_keys: WasmRootWalletKeys, paygo_pubkeys?: WasmECPair[] | null): any; + /** + * Parse transaction with wallet keys to identify wallet inputs/outputs + */ + parse_transaction_with_wallet_keys(wallet_keys: WasmRootWalletKeys, replay_protection: WasmReplayProtection, paygo_pubkeys?: WasmECPair[] | null): any; + /** + * Serialize the PSBT to bytes + * + * # Returns + * The serialized PSBT as a byte array + */ + serialize(): Uint8Array; + /** + * Sign all MuSig2 keypath inputs in a single pass with optimized sighash computation. + * + * This is more efficient than calling `sign_musig2_input()` for each input because + * it reuses the SighashCache across all inputs, avoiding redundant computation of + * sha_prevouts, sha_amounts, sha_scriptpubkeys, sha_sequences, and sha_outputs. + * + * Each MuSig2 input requires a FirstRound from `generate_musig2_nonces()`. + * FirstRounds that have already been consumed (signed) are skipped. + * + * # Arguments + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_all_musig2_inputs(xpriv: WasmBIP32): any; + /** + * Sign all replay protection inputs with a raw private key. + * + * This iterates through all inputs looking for P2SH-P2PK (replay protection) inputs + * that match the provided public key and signs them. + * + * # Arguments + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_all_replay_protection_inputs(ecpair: WasmECPair): any; + /** + * Sign all non-MuSig2 wallet inputs in a single efficient pass. + * + * This signs all ECDSA (P2SH, P2SH-P2WSH, P2WSH) and Taproot script path (P2TR) + * inputs that match the provided xpriv. MuSig2 keypath inputs are skipped. + * + * This is the most efficient way to sign wallet inputs. After calling this, + * sign any MuSig2 inputs using `sign_all_musig2_inputs()` or `sign_musig2_input()`. + * + * # Arguments + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_all_wallet_inputs(xpriv: WasmBIP32): any; + /** + * Sign all non-MuSig2 inputs with an extended private key (xpriv) in a single pass. + * + * This is more efficient than calling `sign_with_xpriv` for each input individually. + * The underlying miniscript library's `sign` method signs all matching inputs at once. + * + * **Note:** MuSig2 inputs are skipped by this method because they require FirstRound + * state from nonce generation. After calling this method, sign MuSig2 inputs + * individually using `sign_with_xpriv`. + * + * # Arguments + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_all_with_xpriv(xpriv: WasmBIP32): any; + /** + * Sign a single MuSig2 keypath input. + * + * This uses the FirstRound state generated by `generate_musig2_nonces()`. + * Each FirstRound can only be used once (nonce reuse is a security risk). + * + * For non-MuSig2 inputs, returns an error (use `sign_wallet_input` instead). + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if signing was successful + * - `Err(WasmUtxoError)` if signing fails, no FirstRound exists, or not a MuSig2 input + */ + sign_musig2_input(input_index: number, xpriv: WasmBIP32): void; + /** + * Sign all replay protection inputs with a raw private key. + * + * This iterates through all inputs looking for P2SH-P2PK (replay protection) inputs + * that match the provided public key and signs them. + * + * # Arguments + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_replay_protection_inputs(ecpair: WasmECPair): any; + /** + * Sign a single input with a raw private key, using save/restore for regular inputs. + * + * For replay protection inputs (P2SH-P2PK), this uses direct signing which is + * already single-input. For regular inputs, this clones the PSBT, signs all, + * then copies only the target input's signatures back. + * + * **Important:** This is NOT faster than signing all inputs for regular (non-RP) inputs. + * The underlying miniscript library signs all inputs regardless. + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(())` if the input was signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_single_input_with_privkey(input_index: number, ecpair: WasmECPair): void; + /** + * Sign a single input with an extended private key, using save/restore for ECDSA inputs. + * + * For MuSig2 inputs, this returns an error (use sign_with_xpriv which handles FirstRound). + * For ECDSA inputs, this clones the PSBT, signs all, then copies only the target + * input's signatures back. + * + * **Important:** This is NOT faster than `sign_all_with_xpriv` for ECDSA inputs. + * The underlying miniscript library signs all inputs regardless. This method + * just prevents signatures from being added to other inputs. + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if the input was signed + * - `Err(WasmUtxoError)` if signing fails + */ + sign_single_input_with_xpriv(input_index: number, xpriv: WasmBIP32): void; + /** + * Sign a single non-MuSig2 wallet input using save/restore pattern. + * + * For MuSig2 inputs, returns an error (use `sign_musig2_input` instead). + * For ECDSA inputs, this uses a save/restore pattern: clones the PSBT, + * signs all inputs on the clone, then copies only the target input's + * signatures back. + * + * **Important:** This is NOT faster than `sign_all_wallet_inputs()` for ECDSA inputs. + * The underlying library signs all inputs regardless. This method just ensures + * that only the specified input gets signatures added to the PSBT. + * Use `sign_all_wallet_inputs()` when signing multiple inputs with the same key. + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if the input was signed + * - `Err(WasmUtxoError)` if signing fails or input is MuSig2 + */ + sign_wallet_input(input_index: number, xpriv: WasmBIP32): void; + /** + * Sign a single input with a raw private key + * + * This method signs a specific input using the provided ECPair. It accepts: + * - A raw privkey (WasmECPair) for replay protection inputs - signs directly + * + * This method automatically detects and handles different input types: + * - For replay protection inputs: signs with legacy P2SH sighash + * - For regular inputs: uses standard PSBT signing + * - For MuSig2 inputs: returns error (requires FirstRound, use sign_with_xpriv instead) + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(())` if signing was successful + * - `Err(WasmUtxoError)` if signing fails + */ + sign_with_privkey(input_index: number, ecpair: WasmECPair): void; + /** + * Sign a single input with an extended private key (xpriv) + * + * This method signs a specific input using the provided xpriv. It accepts: + * - An xpriv (WasmBIP32) for wallet inputs - derives the key and signs + * + * This method automatically detects and handles different input types: + * - For regular inputs: uses standard PSBT signing + * - For MuSig2 inputs: uses the FirstRound state stored by generate_musig2_nonces() + * - For replay protection inputs: returns error (use sign_with_privkey instead) + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if signing was successful + * - `Err(WasmUtxoError)` if signing fails + */ + sign_with_xpriv(input_index: number, xpriv: WasmBIP32): void; + /** + * Get the unsigned transaction ID + */ + unsigned_txid(): string; + /** + * Verify if a replay protection input has a valid signature + * + * This method checks if a given input is a replay protection input and cryptographically verifies + * the signature. Replay protection inputs (like P2shP2pk) don't use standard derivation paths, + * so this method verifies signatures without deriving from xpub. + * + * # Arguments + * - `input_index`: The index of the input to check + * - `replay_protection`: Replay protection configuration (same format as parseTransactionWithWalletKeys) + * Can be either `{ outputScripts: Buffer[] }` or `{ addresses: string[] }` + * + * # Returns + * - `Ok(true)` if the input is a replay protection input and has a valid signature + * - `Ok(false)` if the input is a replay protection input but has no valid signature + * - `Err(WasmUtxoError)` if the input is not a replay protection input, index is out of bounds, or configuration is invalid + */ + verify_replay_protection_signature(input_index: number, replay_protection: WasmReplayProtection): boolean; + /** + * Verify if a valid signature exists for a given ECPair key at the specified input index + * + * This method verifies the signature directly with the provided ECPair's public key. It supports: + * - ECDSA signatures (for legacy/SegWit inputs) + * - Schnorr signatures (for Taproot script path inputs) + * + * Note: This method does NOT support MuSig2 inputs, as MuSig2 requires derivation from xpubs. + * Use `verify_signature_with_xpub` for MuSig2 inputs. + * + * # Arguments + * - `input_index`: The index of the input to check + * - `ecpair`: The ECPair key (uses the public key for verification) + * + * # Returns + * - `Ok(true)` if a valid signature exists for the public key + * - `Ok(false)` if no signature exists for the public key + * - `Err(WasmUtxoError)` if the input index is out of bounds or verification fails + */ + verify_signature_with_pub(input_index: number, ecpair: WasmECPair): boolean; + /** + * Verify if a valid signature exists for a given xpub at the specified input index + * + * This method derives the public key from the xpub using the derivation path found in the + * PSBT input, then verifies the signature. It supports: + * - ECDSA signatures (for legacy/SegWit inputs) + * - Schnorr signatures (for Taproot script path inputs) + * - MuSig2 partial signatures (for Taproot keypath MuSig2 inputs) + * + * # Arguments + * - `input_index`: The index of the input to check + * - `xpub`: The extended public key as a WasmBIP32 instance + * + * # Returns + * - `Ok(true)` if a valid signature exists for the derived public key + * - `Ok(false)` if no signature exists for the derived public key + * - `Err(WasmUtxoError)` if the input index is out of bounds, derivation fails, or verification fails + */ + verify_signature_with_xpub(input_index: number, xpub: WasmBIP32): boolean; + /** + * Get the transaction version + */ + version(): number; + /** + * Get the Zcash version group ID (returns None for non-Zcash PSBTs) + */ + version_group_id(): number | undefined; +} + +export class FixedScriptWalletNamespace { + private constructor(); + free(): void; + [Symbol.dispose](): void; + static address(keys: WasmRootWalletKeys, chain: number, index: number, network: any, address_format?: string | null): string; + static address_with_network_str(keys: WasmRootWalletKeys, chain: number, index: number, network: string, address_format?: string | null): string; + /** + * Get all chain code metadata for building TypeScript lookup tables + * + * Returns an array of [chainCode, scriptType, scope] tuples where: + * - chainCode: u32 (0, 1, 10, 11, 20, 21, 30, 31, 40, 41) + * - scriptType: string ("p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", "p2trMusig2") + * - scope: string ("external" or "internal") + */ + static chain_code_table(): any; + /** + * Create an OP_RETURN output script with optional data + * + * # Arguments + * * `data` - Optional data bytes to include in the OP_RETURN script + * + * # Returns + * The OP_RETURN script as bytes + */ + static create_op_return_script(data?: Uint8Array | null): Uint8Array; + static output_script(keys: WasmRootWalletKeys, chain: number, index: number, network: any): Uint8Array; + static output_script_with_network_str(keys: WasmRootWalletKeys, chain: number, index: number, network: string): Uint8Array; + /** + * Get the P2SH-P2PK output script for a compressed public key + * + * # Arguments + * * `pubkey` - The compressed public key bytes (33 bytes) + * + * # Returns + * The P2SH-P2PK output script as bytes + */ + static p2sh_p2pk_output_script(pubkey: Uint8Array): Uint8Array; + /** + * Check if a network supports a given fixed-script wallet script type + * + * # Arguments + * * `coin` - Coin name (e.g., "btc", "ltc", "doge") + * * `script_type` - Script type name: "p2sh", "p2shP2wsh", "p2wsh", "p2tr", "p2trMusig2" + * + * # Returns + * `true` if the network supports the script type, `false` otherwise + * + * # Examples + * - Bitcoin supports all script types (p2sh, p2shP2wsh, p2wsh, p2tr, p2trMusig2) + * - Litecoin supports segwit but not taproot (p2sh, p2shP2wsh, p2wsh) + * - Dogecoin only supports legacy scripts (p2sh) + */ + static supports_script_type(coin: string, script_type: string): boolean; +} + +/** + * Namespace for inscription-related functions + */ +export class InscriptionsNamespace { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Create inscription reveal data including the commit output script and tap leaf script + * + * # Arguments + * * `x_only_pubkey` - The x-only public key (32 bytes) + * * `content_type` - MIME type of the inscription (e.g., "text/plain", "image/png") + * * `inscription_data` - The inscription data bytes + * + * # Returns + * An object containing: + * - `output_script`: The commit output script (P2TR, network-agnostic) + * - `reveal_transaction_vsize`: Estimated vsize of the reveal transaction + * - `tap_leaf_script`: Object with `leaf_version`, `script`, and `control_block` + */ + static create_inscription_reveal_data(x_only_pubkey: Uint8Array, content_type: string, inscription_data: Uint8Array): any; + /** + * Sign a reveal transaction + * + * # Arguments + * * `private_key` - The private key (32 bytes) + * * `tap_leaf_script` - The tap leaf script object from `create_inscription_reveal_data` + * * `commit_tx` - The commit transaction + * * `commit_output_script` - The commit output script (P2TR) + * * `recipient_output_script` - Where to send the inscription (output script) + * * `output_value_sats` - Value in satoshis for the inscription output + * + * # Returns + * The signed PSBT as bytes + */ + static sign_reveal_transaction(private_key: Uint8Array, tap_leaf_script: any, commit_tx: WasmTransaction, commit_output_script: Uint8Array, recipient_output_script: Uint8Array, output_value_sats: bigint): Uint8Array; +} + +export class MessageNamespace { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Sign a message using Bitcoin message signing (BIP-137) + * + * Returns 65-byte signature (1-byte header + 64-byte signature). + * The key must have a private key (cannot sign with public key only). + */ + static sign_message(key: WasmECPair, message_str: string): Uint8Array; + /** + * Verify a Bitcoin message signature (BIP-137) + * + * Signature must be 65 bytes (1-byte header + 64-byte signature). + * Returns true if the signature is valid for this key. + */ + static verify_message(key: WasmECPair, message_str: string, signature: Uint8Array): boolean; +} + +export class UtxolibCompatNamespace { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Convert output script to address string + * + * # Arguments + * * `script` - The output script as a byte array + * * `network` - The UtxolibNetwork object from JavaScript + * * `format` - Optional address format: "default" or "cashaddr" (only applicable for Bitcoin Cash and eCash) + */ + static from_output_script(script: Uint8Array, network: any, format?: string | null): string; + /** + * Convert address string to output script + * + * # Arguments + * * `address` - The address string + * * `network` - The UtxolibNetwork object from JavaScript + * * `format` - Optional address format (currently unused for decoding as all formats are accepted) + */ + static to_output_script(address: string, network: any, format?: string | null): Uint8Array; +} + +/** + * WASM wrapper for BIP32 extended keys (Xpub/Xpriv) + * Implements the BIP32Interface TypeScript interface + */ +export class WasmBIP32 { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Derive a normal (non-hardened) child key + */ + derive(index: number): WasmBIP32; + /** + * Derive a hardened child key (only works for private keys) + */ + derive_hardened(index: number): WasmBIP32; + /** + * Derive a key using a derivation path (e.g., "0/1/2" or "m/0/1/2") + */ + derive_path(path: string): WasmBIP32; + /** + * Check equality with another WasmBIP32 key. + * Two keys are equal if they have the same type (public/private) and identical + * BIP32 metadata (depth, parent fingerprint, child index, chain code, key data). + */ + equals(other: WasmBIP32): boolean; + /** + * Create a BIP32 key from a base58 string (xpub/xprv/tpub/tprv) + */ + static from_base58(base58_str: string): WasmBIP32; + /** + * Create a BIP32 key from a BIP32Interface JavaScript object properties + * Expects an object with: network.bip32.public, depth, parentFingerprint, + * index, chainCode, and publicKey properties + */ + static from_bip32_interface(bip32_key: any): WasmBIP32; + /** + * Create a BIP32 key from BIP32 properties + * Extracts properties from a JavaScript object and constructs an xpub or xprv + */ + static from_bip32_properties(bip32_key: any): WasmBIP32; + /** + * Create a BIP32 master key from a seed + */ + static from_seed(seed: Uint8Array, network?: string | null): WasmBIP32; + /** + * Create a BIP32 master key from a string by hashing it with SHA256. + * This is useful for deterministic test key generation. + */ + static from_seed_sha256(seed_string: string, network?: string | null): WasmBIP32; + /** + * Create a BIP32 key from an xprv string (base58-encoded) + */ + static from_xprv(xprv_str: string): WasmBIP32; + /** + * Create a BIP32 key from an xpub string (base58-encoded) + */ + static from_xpub(xpub_str: string): WasmBIP32; + /** + * Check if this is a neutered (public) key + */ + is_neutered(): boolean; + /** + * Get the neutered (public) version of this key + */ + neutered(): WasmBIP32; + /** + * Serialize to base58 string + */ + to_base58(): string; + /** + * Get the WIF encoding of the private key + */ + to_wif(): string; + /** + * Get the chain code as a Uint8Array + */ + readonly chain_code: Uint8Array; + /** + * Get the depth + */ + readonly depth: number; + /** + * Get the fingerprint as a Uint8Array + */ + readonly fingerprint: Uint8Array; + /** + * Get the identifier as a Uint8Array + */ + readonly identifier: Uint8Array; + /** + * Get the child index + */ + readonly index: number; + /** + * Get the parent fingerprint + */ + readonly parent_fingerprint: number; + /** + * Get the private key as a Uint8Array (if available) + */ + readonly private_key: Uint8Array | undefined; + /** + * Get the public key as a Uint8Array + */ + readonly public_key: Uint8Array; +} + +/** + * Dash transaction wrapper that supports Dash special transactions (EVO) by preserving extra payload. + */ +export class WasmDashTransaction { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Deserialize a Dash transaction from bytes (supports EVO special tx extra payload). + */ + static from_bytes(bytes: Uint8Array): WasmDashTransaction; + /** + * Get the transaction ID (txid) + * + * The txid is the double SHA256 of the full Dash transaction bytes, + * displayed in reverse byte order (big-endian) as is standard. + * + * # Returns + * The transaction ID as a hex string + * + * # Errors + * Returns an error if the transaction cannot be serialized + */ + get_txid(): string; + /** + * Serialize the Dash transaction to bytes (preserving tx_type and extra payload). + */ + to_bytes(): Uint8Array; +} + +/** + * Dimensions for estimating transaction virtual size. + * + * Tracks weight internally with min/max bounds to handle ECDSA signature variance. + * Schnorr signatures have no variance (always 64 bytes). + */ +export class WasmDimensions { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Create empty dimensions (zero weight) + */ + static empty(): WasmDimensions; + /** + * Create dimensions for a single input from chain code + * + * # Arguments + * * `chain` - Chain code (0/1=p2sh, 10/11=p2shP2wsh, 20/21=p2wsh, 30/31=p2tr, 40/41=p2trMusig2) + * * `signer` - Optional signer key ("user", "backup", "bitgo") + * * `cosigner` - Optional cosigner key ("user", "backup", "bitgo") + * * `compat` - When true, use 72-byte signatures for max (matches @bitgo/unspents) + */ + static from_input(chain: number, signer?: string | null, cosigner?: string | null, compat?: boolean | null): WasmDimensions; + /** + * Create dimensions for a single input from script type string + * + * # Arguments + * * `script_type` - One of: "p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", + * "p2trMusig2KeyPath", "p2trMusig2ScriptPath", "p2shP2pk" + * * `compat` - When true, use 72-byte signatures for max (matches @bitgo/unspents) + */ + static from_input_script_type(script_type: string, compat?: boolean | null): WasmDimensions; + /** + * Create dimensions for a single output from script length + */ + static from_output_script_length(length: number): WasmDimensions; + /** + * Create dimensions for a single output from script type string + * + * # Arguments + * * `script_type` - One of: "p2sh", "p2shP2wsh", "p2wsh", "p2tr"/"p2trLegacy", "p2trMusig2" + */ + static from_output_script_type(script_type: string): WasmDimensions; + /** + * Create dimensions from a BitGoPsbt + * + * Parses PSBT inputs and outputs to compute weight bounds without + * requiring wallet keys. Input types are detected from BIP32 derivation + * paths stored in the PSBT. + */ + static from_psbt(psbt: BitGoPsbt): WasmDimensions; + /** + * Get input virtual size (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + */ + get_input_vsize(size?: string | null): number; + /** + * Get input weight only (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + */ + get_input_weight(size?: string | null): number; + /** + * Get output virtual size + */ + get_output_vsize(): number; + /** + * Get output weight + */ + get_output_weight(): number; + /** + * Get virtual size (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + */ + get_vsize(size?: string | null): number; + /** + * Get total weight (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + */ + get_weight(size?: string | null): number; + /** + * Whether any inputs are segwit (affects overhead calculation) + */ + has_segwit(): boolean; + /** + * Combine with another Dimensions instance + */ + plus(other: WasmDimensions): WasmDimensions; + /** + * Multiply dimensions by a scalar + */ + times(n: number): WasmDimensions; +} + +/** + * WASM wrapper for elliptic curve key pairs (always uses compressed keys) + */ +export class WasmECPair { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Create an ECPair from a private key (always uses compressed keys) + */ + static from_private_key(private_key: Uint8Array): WasmECPair; + /** + * Create an ECPair from a public key (always uses compressed keys) + */ + static from_public_key(public_key: Uint8Array): WasmECPair; + /** + * Create an ECPair from a WIF string (auto-detects network) + */ + static from_wif(wif_string: string): WasmECPair; + /** + * Create an ECPair from a mainnet WIF string + */ + static from_wif_mainnet(wif_string: string): WasmECPair; + /** + * Create an ECPair from a testnet WIF string + */ + static from_wif_testnet(wif_string: string): WasmECPair; + /** + * Convert to WIF string (mainnet) + */ + to_wif(): string; + /** + * Convert to mainnet WIF string + */ + to_wif_mainnet(): string; + /** + * Convert to testnet WIF string + */ + to_wif_testnet(): string; + /** + * Get the private key as a Uint8Array (if available) + */ + readonly private_key: Uint8Array | undefined; + /** + * Get the compressed public key as a Uint8Array (always 33 bytes) + */ + readonly public_key: Uint8Array; +} + +/** + * WASM wrapper for ReplayProtection + */ +export class WasmReplayProtection { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Create from addresses (requires network for decoding) + */ + static from_addresses(addresses: any[], network: string): WasmReplayProtection; + /** + * Create from output scripts directly + */ + static from_output_scripts(output_scripts: Uint8Array[]): WasmReplayProtection; + /** + * Create from public keys (derives P2SH-P2PK output scripts) + */ + static from_public_keys(public_keys: Uint8Array[]): WasmReplayProtection; +} + +/** + * WASM wrapper for RootWalletKeys + * Represents a set of three extended public keys with their derivation prefixes + */ +export class WasmRootWalletKeys { + free(): void; + [Symbol.dispose](): void; + /** + * Get the backup key (second xpub) + */ + backup_key(): WasmBIP32; + /** + * Get the bitgo key (third xpub) + */ + bitgo_key(): WasmBIP32; + /** + * Create a RootWalletKeys from three BIP32 keys + * Uses default derivation prefix of m/0/0 for all three keys + * + * # Arguments + * - `user`: User key (first xpub) + * - `backup`: Backup key (second xpub) + * - `bitgo`: BitGo key (third xpub) + */ + constructor(user: WasmBIP32, backup: WasmBIP32, bitgo: WasmBIP32); + /** + * Get the user key (first xpub) + */ + user_key(): WasmBIP32; + /** + * Create a RootWalletKeys from three BIP32 keys with custom derivation prefixes + * + * # Arguments + * - `user`: User key (first xpub) + * - `backup`: Backup key (second xpub) + * - `bitgo`: BitGo key (third xpub) + * - `user_derivation`: Derivation path for user key (e.g., "m/0/0") + * - `backup_derivation`: Derivation path for backup key (e.g., "m/0/0") + * - `bitgo_derivation`: Derivation path for bitgo key (e.g., "m/0/0") + */ + static with_derivation_prefixes(user: WasmBIP32, backup: WasmBIP32, bitgo: WasmBIP32, user_derivation: string, backup_derivation: string, bitgo_derivation: string): WasmRootWalletKeys; +} + +/** + * A Bitcoin-like transaction (for all networks except Zcash) + * + * This class provides basic transaction parsing and serialization for testing + * compatibility with third-party transaction fixtures. + */ +export class WasmTransaction { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Add an input to the transaction + * + * # Arguments + * * `txid` - The transaction ID (hex string) of the output being spent + * * `vout` - The output index being spent + * * `sequence` - Optional sequence number (default: 0xFFFFFFFF) + * + * # Returns + * The index of the newly added input + */ + add_input(txid: string, vout: number, sequence?: number | null): number; + /** + * Add an output to the transaction + * + * # Arguments + * * `script` - The output script (scriptPubKey) + * * `value` - The value in satoshis + * + * # Returns + * The index of the newly added output + */ + add_output(script: Uint8Array, value: bigint): number; + /** + * Create an empty transaction (version 1, locktime 0) + */ + static create(): WasmTransaction; + /** + * Deserialize a transaction from bytes + * + * # Arguments + * * `bytes` - The serialized transaction bytes + * + * # Returns + * A WasmTransaction instance + * + * # Errors + * Returns an error if the bytes cannot be parsed as a valid transaction + */ + static from_bytes(bytes: Uint8Array): WasmTransaction; + /** + * Get the transaction ID (txid) + * + * The txid is the double SHA256 of the transaction bytes (excluding witness + * data for segwit transactions), displayed in reverse byte order (big-endian) + * as is standard for Bitcoin. + * + * # Returns + * The transaction ID as a hex string + */ + get_txid(): string; + /** + * Get the virtual size of the transaction + * + * Virtual size is calculated as ceil(weight / 4), where weight accounts + * for the segwit discount on witness data. + * + * # Returns + * The virtual size in virtual bytes (vbytes) + */ + get_vsize(): number; + /** + * Serialize the transaction to bytes + * + * # Returns + * The serialized transaction bytes + */ + to_bytes(): Uint8Array; +} + +/** + * A Zcash transaction with network-specific fields + * + * This class provides basic transaction parsing and serialization for Zcash + * transactions, which use the Overwinter transaction format. + */ +export class WasmZcashTransaction { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * Deserialize a Zcash transaction from bytes + * + * # Arguments + * * `bytes` - The serialized transaction bytes + * + * # Returns + * A WasmZcashTransaction instance + * + * # Errors + * Returns an error if the bytes cannot be parsed as a valid Zcash transaction + */ + static from_bytes(bytes: Uint8Array): WasmZcashTransaction; + /** + * Get the transaction ID (txid) + * + * The txid is the double SHA256 of the full Zcash transaction bytes, + * displayed in reverse byte order (big-endian) as is standard. + * + * # Returns + * The transaction ID as a hex string + * + * # Errors + * Returns an error if the transaction cannot be serialized + */ + get_txid(): string; + /** + * Serialize the transaction to bytes + * + * # Returns + * The serialized transaction bytes + */ + to_bytes(): Uint8Array; +} + +export class WrapDescriptor { + private constructor(); + free(): void; + [Symbol.dispose](): void; + atDerivationIndex(index: number): WrapDescriptor; + descType(): any; + encode(): Uint8Array; + hasWildcard(): boolean; + maxWeightToSatisfy(): number; + node(): any; + scriptPubkey(): Uint8Array; + toAsmString(): string; + toString(): string; +} + +export class WrapMiniscript { + private constructor(); + free(): void; + [Symbol.dispose](): void; + encode(): Uint8Array; + node(): any; + toAsmString(): string; + toString(): string; +} + +export class WrapPsbt { + free(): void; + [Symbol.dispose](): void; + /** + * Add an input to the PSBT + * + * # Arguments + * * `txid` - Transaction ID (hex string, 32 bytes reversed) + * * `vout` - Output index being spent + * * `value` - Value in satoshis of the output being spent + * * `script` - The scriptPubKey of the output being spent + * * `sequence` - Sequence number (default: 0xFFFFFFFE for RBF) + * + * # Returns + * The index of the newly added input + */ + addInput(txid: string, vout: number, value: bigint, script: Uint8Array, sequence?: number | null): number; + /** + * Add an output to the PSBT + * + * # Arguments + * * `script` - The output script (scriptPubKey) + * * `value` - Value in satoshis + * + * # Returns + * The index of the newly added output + */ + addOutput(script: Uint8Array, value: bigint): number; + clone(): WrapPsbt; + static deserialize(psbt: Uint8Array): WrapPsbt; + /** + * Extract the final transaction from a finalized PSBT + * + * This method should be called after all inputs have been finalized. + * It extracts the fully signed transaction as a WasmTransaction instance. + * + * # Returns + * - `Ok(WasmTransaction)` containing the extracted transaction + * - `Err(WasmUtxoError)` if the PSBT is not fully finalized or extraction fails + */ + extractTransaction(): WasmTransaction; + finalize(): void; + /** + * Get all PSBT inputs as an array of PsbtInputData + * + * Returns an array with witness_utxo, bip32_derivation, and tap_bip32_derivation + * for each input. This is useful for introspecting the PSBT structure. + */ + getInputs(): any; + /** + * Get all PSBT outputs as an array of PsbtOutputData + * + * Returns an array with script, value, bip32_derivation, and tap_bip32_derivation + * for each output. This is useful for introspecting the PSBT structure. + */ + getOutputs(): any; + /** + * Get all PSBT outputs with resolved address strings. + * + * Like `getOutputs()` but each element also includes an `address` field + * derived from the output script using the given coin name (e.g. "btc", "tbtc"). + */ + getOutputsWithAddress(coin: string): any; + /** + * Get partial signatures for an input + * Returns array of { pubkey: Uint8Array, signature: Uint8Array } + */ + getPartialSignatures(input_index: number): any; + /** + * Get the unsigned transaction bytes + * + * # Returns + * The serialized unsigned transaction + */ + getUnsignedTx(): Uint8Array; + /** + * Check if an input has any partial signatures + */ + hasPartialSignatures(input_index: number): boolean; + /** + * Get the number of inputs in the PSBT + */ + inputCount(): number; + /** + * Get the transaction lock time + */ + lockTime(): number; + /** + * Create an empty PSBT + * + * # Arguments + * * `version` - Transaction version (default: 2) + * * `lock_time` - Transaction lock time (default: 0) + */ + constructor(version?: number | null, lock_time?: number | null); + /** + * Get the number of outputs in the PSBT + */ + outputCount(): number; + /** + * Remove an output from the PSBT by index. + * + * Removes both the transaction output and the PSBT output metadata. + */ + removeOutput(index: number): void; + serialize(): Uint8Array; + /** + * Sign all inputs with a WasmBIP32 key + * + * This method signs all inputs that match the BIP32 derivation paths in the PSBT. + * Returns a map of input indices to the public keys that were signed. + * + * # Arguments + * * `key` - The WasmBIP32 key to sign with + * + * # Returns + * A SigningKeysMap converted to JsValue (object mapping input indices to signing keys) + */ + signAll(key: WasmBIP32): any; + /** + * Sign all inputs with a WasmECPair key + * + * This method signs all inputs using the private key from the ECPair. + * Returns a map of input indices to the public keys that were signed. + * + * # Arguments + * * `key` - The WasmECPair key to sign with + * + * # Returns + * A SigningKeysMap converted to JsValue (object mapping input indices to signing keys) + */ + signAllWithEcpair(key: WasmECPair): any; + signWithPrv(prv: Uint8Array): any; + signWithXprv(xprv: string): any; + /** + * Get the unsigned transaction ID as a hex string + */ + unsignedTxId(): string; + updateInputWithDescriptor(input_index: number, descriptor: WrapDescriptor): void; + updateOutputWithDescriptor(output_index: number, descriptor: WrapDescriptor): void; + /** + * Validate a signature at a specific input against a pubkey + * Returns true if the signature is valid + * + * This method handles both ECDSA (legacy/SegWit) and Schnorr (Taproot) signatures. + * The pubkey should be provided as bytes (33 bytes for compressed ECDSA, 32 bytes for x-only Schnorr). + */ + validateSignatureAtInput(input_index: number, pubkey: Uint8Array): boolean; + /** + * Verify a signature at a specific input using a WasmBIP32 key + * + * This method verifies if a valid signature exists for the given BIP32 key at the specified input. + * It handles both ECDSA (legacy/SegWit) and Schnorr (Taproot) signatures. + * + * Note: This method checks if the key's public key matches any signature in the input. + * For proper BIP32 verification, the key should be derived to the correct path first. + * + * # Arguments + * * `input_index` - The index of the input to check + * * `key` - The WasmBIP32 key to verify against + * + * # Returns + * `true` if a valid signature exists for the key, `false` otherwise + */ + verifySignatureWithKey(input_index: number, key: WasmBIP32): boolean; + /** + * Get the transaction version + */ + version(): number; +} + +/** + * Check if the inspect feature is enabled. + * + * # Returns + * `true` if the feature is enabled, `false` otherwise + */ +export function isInspectEnabled(): boolean; + +/** + * Parse a PSBT at the raw byte level and return a JSON representation. + * + * Unlike `parsePsbtToJson`, this function exposes the raw key-value pair + * structure as defined in BIP-174, showing: + * - Raw key type IDs and their human-readable names + * - Proprietary keys with their structured format + * - Unknown/unrecognized keys that standard parsers might skip + * + * # Arguments + * * `psbt_bytes` - The raw PSBT bytes + * * `coin_name` - The network coin name (e.g., "btc", "ltc", "zec") + * + * # Returns + * A JSON string representing the raw PSBT key-value structure + * + * # Errors + * Returns an error if: + * - The `inspect` feature is not enabled + * - The PSBT bytes are invalid + * - The network name is unknown + */ +export function parsePsbtRawToJson(psbt_bytes: Uint8Array, coin_name: string): string; + +/** + * Parse a PSBT and return a JSON representation of its structure. + * + * This function parses the PSBT using the standard bitcoin crate parser + * and returns a hierarchical node structure suitable for display. + * + * # Arguments + * * `psbt_bytes` - The raw PSBT bytes + * * `coin_name` - The network coin name (e.g., "btc", "ltc", "bch") + * + * # Returns + * A JSON string representing the parsed PSBT structure + * + * # Errors + * Returns an error if: + * - The `inspect` feature is not enabled + * - The PSBT bytes are invalid + * - The network name is unknown + */ +export function parsePsbtToJson(psbt_bytes: Uint8Array, coin_name: string): string; + +/** + * Parse a transaction and return a JSON representation of its structure. + * + * # Arguments + * * `tx_bytes` - The raw transaction bytes + * * `coin_name` - The network coin name (e.g., "btc", "ltc", "bch") + * + * # Returns + * A JSON string representing the parsed transaction structure + * + * # Errors + * Returns an error if: + * - The `inspect` feature is not enabled + * - The transaction bytes are invalid + * - The network name is unknown + */ +export function parseTxToJson(tx_bytes: Uint8Array, coin_name: string): string; diff --git a/packages/webui/wasm/wasm_utxo.js b/packages/webui/wasm/wasm_utxo.js new file mode 100644 index 00000000..fab56f79 --- /dev/null +++ b/packages/webui/wasm/wasm_utxo.js @@ -0,0 +1,9 @@ +/* @ts-self-types="./wasm_utxo.d.ts" */ + +import * as wasm from "./wasm_utxo_bg.wasm"; +import { __wbg_set_wasm } from "./wasm_utxo_bg.js"; +__wbg_set_wasm(wasm); + +export { + AddressNamespace, Bip322Namespace, BitGoPsbt, FixedScriptWalletNamespace, InscriptionsNamespace, MessageNamespace, UtxolibCompatNamespace, WasmBIP32, WasmDashTransaction, WasmDimensions, WasmECPair, WasmReplayProtection, WasmRootWalletKeys, WasmTransaction, WasmZcashTransaction, WrapDescriptor, WrapMiniscript, WrapPsbt, isInspectEnabled, parsePsbtRawToJson, parsePsbtToJson, parseTxToJson +} from "./wasm_utxo_bg.js"; diff --git a/packages/webui/wasm/wasm_utxo_bg.js b/packages/webui/wasm/wasm_utxo_bg.js new file mode 100644 index 00000000..2afcfbaa --- /dev/null +++ b/packages/webui/wasm/wasm_utxo_bg.js @@ -0,0 +1,5379 @@ +export class AddressNamespace { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + AddressNamespaceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_addressnamespace_free(ptr, 0); + } + /** + * @param {Uint8Array} script + * @param {string} coin + * @param {string | null} [format] + * @returns {string} + */ + static from_output_script_with_coin(script, coin, format) { + let deferred5_0; + let deferred5_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(coin, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + var ptr2 = isLikeNone(format) ? 0 : passStringToWasm0(format, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len2 = WASM_VECTOR_LEN; + wasm.addressnamespace_from_output_script_with_coin(retptr, ptr0, len0, ptr1, len1, ptr2, len2); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr4 = r0; + var len4 = r1; + if (r3) { + ptr4 = 0; len4 = 0; + throw takeObject(r2); + } + deferred5_0 = ptr4; + deferred5_1 = len4; + return getStringFromWasm0(ptr4, len4); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred5_0, deferred5_1, 1); + } + } + /** + * @param {string} address + * @param {string} coin + * @returns {Uint8Array} + */ + static to_output_script_with_coin(address, coin) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(address, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(coin, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.addressnamespace_to_output_script_with_coin(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v3 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v3; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) AddressNamespace.prototype[Symbol.dispose] = AddressNamespace.prototype.free; + +/** + * Namespace for BIP-0322 functions + */ +export class Bip322Namespace { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + Bip322NamespaceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_bip322namespace_free(ptr, 0); + } + /** + * Add a BIP-0322 message input to an existing BitGoPsbt + * + * If this is the first input, also adds the OP_RETURN output. + * The PSBT must have version 0 per BIP-0322 specification. + * + * # Arguments + * * `psbt` - The BitGoPsbt to add the input to + * * `message` - The message to sign + * * `chain` - The wallet chain (e.g., 10 for external, 20 for internal) + * * `index` - The address index + * * `wallet_keys` - The wallet's root keys + * * `signer` - Optional signer key name for taproot (e.g., "user", "backup", "bitgo") + * * `cosigner` - Optional cosigner key name for taproot + * * `tag` - Optional custom tag for message hashing + * + * # Returns + * The index of the added input + * @param {BitGoPsbt} psbt + * @param {string} message + * @param {number} chain + * @param {number} index + * @param {WasmRootWalletKeys} wallet_keys + * @param {string | null} [signer] + * @param {string | null} [cosigner] + * @param {string | null} [tag] + * @returns {number} + */ + static add_bip322_input(psbt, message, chain, index, wallet_keys, signer, cosigner, tag) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(psbt, BitGoPsbt); + const ptr0 = passStringToWasm0(message, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + var ptr1 = isLikeNone(signer) ? 0 : passStringToWasm0(signer, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + var ptr2 = isLikeNone(cosigner) ? 0 : passStringToWasm0(cosigner, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len2 = WASM_VECTOR_LEN; + var ptr3 = isLikeNone(tag) ? 0 : passStringToWasm0(tag, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len3 = WASM_VECTOR_LEN; + wasm.bip322namespace_add_bip322_input(retptr, psbt.__wbg_ptr, ptr0, len0, chain, index, wallet_keys.__wbg_ptr, ptr1, len1, ptr2, len2, ptr3, len3); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify a single input of a BIP-0322 PSBT proof + * + * # Arguments + * * `psbt` - The signed BitGoPsbt + * * `input_index` - The index of the input to verify + * * `message` - The message that was signed + * * `chain` - The wallet chain + * * `index` - The address index + * * `wallet_keys` - The wallet's root keys + * * `tag` - Optional custom tag for message hashing + * + * # Returns + * An array of signer names ("user", "backup", "bitgo") that have valid signatures + * + * # Throws + * Throws an error if verification fails or no valid signatures found + * @param {BitGoPsbt} psbt + * @param {number} input_index + * @param {string} message + * @param {number} chain + * @param {number} index + * @param {WasmRootWalletKeys} wallet_keys + * @param {string | null} [tag] + * @returns {string[]} + */ + static verify_bip322_psbt_input(psbt, input_index, message, chain, index, wallet_keys, tag) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(psbt, BitGoPsbt); + const ptr0 = passStringToWasm0(message, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + var ptr1 = isLikeNone(tag) ? 0 : passStringToWasm0(tag, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.bip322namespace_verify_bip322_psbt_input(retptr, psbt.__wbg_ptr, input_index, ptr0, len0, chain, index, wallet_keys.__wbg_ptr, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v3 = getArrayJsValueFromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 4, 4); + return v3; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify a single input of a BIP-0322 PSBT proof using pubkeys directly + * + * # Arguments + * * `psbt` - The signed BitGoPsbt + * * `input_index` - The index of the input to verify + * * `message` - The message that was signed + * * `pubkeys` - Array of 3 hex-encoded pubkeys [user, backup, bitgo] + * * `script_type` - One of: "p2sh", "p2shP2wsh", "p2wsh", "p2tr", "p2trMusig2" + * * `is_script_path` - For taproot types, whether script path was used + * * `tag` - Optional custom tag for message hashing + * + * # Returns + * An array of pubkey indices (0, 1, 2) that have valid signatures + * + * # Throws + * Throws an error if verification fails or no valid signatures found + * @param {BitGoPsbt} psbt + * @param {number} input_index + * @param {string} message + * @param {string[]} pubkeys + * @param {string} script_type + * @param {boolean | null} [is_script_path] + * @param {string | null} [tag] + * @returns {Uint32Array} + */ + static verify_bip322_psbt_input_with_pubkeys(psbt, input_index, message, pubkeys, script_type, is_script_path, tag) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(psbt, BitGoPsbt); + const ptr0 = passStringToWasm0(message, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArrayJsValueToWasm0(pubkeys, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(script_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len2 = WASM_VECTOR_LEN; + var ptr3 = isLikeNone(tag) ? 0 : passStringToWasm0(tag, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len3 = WASM_VECTOR_LEN; + wasm.bip322namespace_verify_bip322_psbt_input_with_pubkeys(retptr, psbt.__wbg_ptr, input_index, ptr0, len0, ptr1, len1, ptr2, len2, isLikeNone(is_script_path) ? 0xFFFFFF : is_script_path ? 1 : 0, ptr3, len3); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v5 = getArrayU32FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 4, 4); + return v5; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify a single input of a BIP-0322 transaction proof + * + * # Arguments + * * `tx` - The signed transaction + * * `input_index` - The index of the input to verify + * * `message` - The message that was signed + * * `chain` - The wallet chain + * * `index` - The address index + * * `wallet_keys` - The wallet's root keys + * * `network` - Network name + * * `tag` - Optional custom tag for message hashing + * + * # Throws + * Throws an error if verification fails + * @param {WasmTransaction} tx + * @param {number} input_index + * @param {string} message + * @param {number} chain + * @param {number} index + * @param {WasmRootWalletKeys} wallet_keys + * @param {string} network + * @param {string | null} [tag] + */ + static verify_bip322_tx_input(tx, input_index, message, chain, index, wallet_keys, network, tag) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(tx, WasmTransaction); + const ptr0 = passStringToWasm0(message, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + const ptr1 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + var ptr2 = isLikeNone(tag) ? 0 : passStringToWasm0(tag, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len2 = WASM_VECTOR_LEN; + wasm.bip322namespace_verify_bip322_tx_input(retptr, tx.__wbg_ptr, input_index, ptr0, len0, chain, index, wallet_keys.__wbg_ptr, ptr1, len1, ptr2, len2); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify a single input of a BIP-0322 transaction proof using pubkeys directly + * + * # Arguments + * * `tx` - The signed transaction + * * `input_index` - The index of the input to verify + * * `message` - The message that was signed + * * `pubkeys` - Array of 3 hex-encoded pubkeys [user, backup, bitgo] + * * `script_type` - One of: "p2sh", "p2shP2wsh", "p2wsh", "p2tr", "p2trMusig2" + * * `is_script_path` - For taproot types, whether script path was used + * * `tag` - Optional custom tag for message hashing + * + * # Returns + * An array of pubkey indices (0, 1, 2) that have valid signatures + * + * # Throws + * Throws an error if verification fails + * @param {WasmTransaction} tx + * @param {number} input_index + * @param {string} message + * @param {string[]} pubkeys + * @param {string} script_type + * @param {boolean | null} [is_script_path] + * @param {string | null} [tag] + * @returns {Uint32Array} + */ + static verify_bip322_tx_input_with_pubkeys(tx, input_index, message, pubkeys, script_type, is_script_path, tag) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(tx, WasmTransaction); + const ptr0 = passStringToWasm0(message, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArrayJsValueToWasm0(pubkeys, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(script_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len2 = WASM_VECTOR_LEN; + var ptr3 = isLikeNone(tag) ? 0 : passStringToWasm0(tag, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len3 = WASM_VECTOR_LEN; + wasm.bip322namespace_verify_bip322_tx_input_with_pubkeys(retptr, tx.__wbg_ptr, input_index, ptr0, len0, ptr1, len1, ptr2, len2, isLikeNone(is_script_path) ? 0xFFFFFF : is_script_path ? 1 : 0, ptr3, len3); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v5 = getArrayU32FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 4, 4); + return v5; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) Bip322Namespace.prototype[Symbol.dispose] = Bip322Namespace.prototype.free; + +export class BitGoPsbt { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(BitGoPsbt.prototype); + obj.__wbg_ptr = ptr; + BitGoPsbtFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + BitGoPsbtFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_bitgopsbt_free(ptr, 0); + } + /** + * Add an input to the PSBT + * + * # Arguments + * * `txid` - The transaction ID (hex string) of the output being spent + * * `vout` - The output index being spent + * * `value` - The value in satoshis of the output being spent + * * `script` - The output script (scriptPubKey) of the output being spent + * * `sequence` - Optional sequence number (default: 0xFFFFFFFE for RBF) + * + * # Returns + * The index of the newly added input + * @param {string} txid + * @param {number} vout + * @param {bigint} value + * @param {Uint8Array} script + * @param {number | null} [sequence] + * @param {Uint8Array | null} [prev_tx] + * @returns {number} + */ + add_input(txid, vout, value, script, sequence, prev_tx) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(txid, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + var ptr2 = isLikeNone(prev_tx) ? 0 : passArray8ToWasm0(prev_tx, wasm.__wbindgen_export); + var len2 = WASM_VECTOR_LEN; + wasm.bitgopsbt_add_input(retptr, this.__wbg_ptr, ptr0, len0, vout, value, ptr1, len1, isLikeNone(sequence) ? 0x100000001 : (sequence) >>> 0, ptr2, len2); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add an output to the PSBT + * + * # Arguments + * * `script` - The output script (scriptPubKey) + * * `value` - The value in satoshis + * + * # Returns + * The index of the newly added output + * @param {Uint8Array} script + * @param {bigint} value + * @returns {number} + */ + add_output(script, value) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.bitgopsbt_add_output(retptr, this.__wbg_ptr, ptr0, len0, value); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add an output to the PSBT by address + * + * # Arguments + * * `address` - The destination address + * * `value` - The value in satoshis + * + * # Returns + * The index of the newly added output + * @param {string} address + * @param {bigint} value + * @returns {number} + */ + add_output_with_address(address, value) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(address, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.bitgopsbt_add_output_with_address(retptr, this.__wbg_ptr, ptr0, len0, value); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add a PayGo attestation to a PSBT output + * + * # Arguments + * - `output_index`: The index of the output to add the attestation to + * - `entropy`: 64 bytes of entropy + * - `signature`: ECDSA signature bytes + * + * # Returns + * - `Ok(())` if the attestation was successfully added + * - `Err(WasmUtxoError)` if the output index is out of bounds or entropy is invalid + * @param {number} output_index + * @param {Uint8Array} entropy + * @param {Uint8Array} signature + */ + add_paygo_attestation(output_index, entropy, signature) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(entropy, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(signature, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + wasm.bitgopsbt_add_paygo_attestation(retptr, this.__wbg_ptr, output_index, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add a replay protection input to the PSBT + * + * Replay protection inputs are P2SH-P2PK inputs used on forked networks to prevent + * transaction replay attacks. They use a simple pubkey script without wallet derivation. + * + * # Arguments + * * `ecpair` - The ECPair containing the public key for the replay protection input + * * `txid` - The transaction ID (hex string) of the output being spent + * * `vout` - The output index being spent + * * `value` - The value in satoshis + * * `sequence` - Optional sequence number (default: 0xFFFFFFFE for RBF) + * + * # Returns + * The index of the newly added input + * @param {WasmECPair} ecpair + * @param {string} txid + * @param {number} vout + * @param {bigint} value + * @param {number | null} [sequence] + * @param {Uint8Array | null} [prev_tx] + * @returns {number} + */ + add_replay_protection_input(ecpair, txid, vout, value, sequence, prev_tx) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(ecpair, WasmECPair); + const ptr0 = passStringToWasm0(txid, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(prev_tx) ? 0 : passArray8ToWasm0(prev_tx, wasm.__wbindgen_export); + var len1 = WASM_VECTOR_LEN; + wasm.bitgopsbt_add_replay_protection_input(retptr, this.__wbg_ptr, ecpair.__wbg_ptr, ptr0, len0, vout, value, isLikeNone(sequence) ? 0x100000001 : (sequence) >>> 0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add a wallet input with full PSBT metadata + * + * This is a higher-level method that adds an input and populates all required + * PSBT fields (scripts, derivation info, etc.) based on the wallet's chain type. + * + * # Arguments + * * `txid` - The transaction ID (hex string) + * * `vout` - The output index being spent + * * `value` - The value in satoshis + * * `chain` - The chain code (0/1=p2sh, 10/11=p2shP2wsh, 20/21=p2wsh, 30/31=p2tr, 40/41=p2trMusig2) + * * `index` - The derivation index + * * `wallet_keys` - The root wallet keys + * * `signer` - The key that will sign ("user", "backup", or "bitgo") - required for p2tr/p2trMusig2 + * * `cosigner` - The key that will co-sign - required for p2tr/p2trMusig2 + * * `sequence` - Optional sequence number (default: 0xFFFFFFFE for RBF) + * * `prev_tx` - Optional full previous transaction bytes (for non-segwit) + * + * # Returns + * The index of the newly added input + * @param {string} txid + * @param {number} vout + * @param {bigint} value + * @param {WasmRootWalletKeys} wallet_keys + * @param {number} chain + * @param {number} index + * @param {string | null} [signer] + * @param {string | null} [cosigner] + * @param {number | null} [sequence] + * @param {Uint8Array | null} [prev_tx] + * @returns {number} + */ + add_wallet_input(txid, vout, value, wallet_keys, chain, index, signer, cosigner, sequence, prev_tx) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(txid, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + var ptr1 = isLikeNone(signer) ? 0 : passStringToWasm0(signer, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + var ptr2 = isLikeNone(cosigner) ? 0 : passStringToWasm0(cosigner, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len2 = WASM_VECTOR_LEN; + var ptr3 = isLikeNone(prev_tx) ? 0 : passArray8ToWasm0(prev_tx, wasm.__wbindgen_export); + var len3 = WASM_VECTOR_LEN; + wasm.bitgopsbt_add_wallet_input(retptr, this.__wbg_ptr, ptr0, len0, vout, value, wallet_keys.__wbg_ptr, chain, index, ptr1, len1, ptr2, len2, isLikeNone(sequence) ? 0x100000001 : (sequence) >>> 0, ptr3, len3); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add a wallet output with full PSBT metadata + * + * This creates a verifiable wallet output (typically for change) with all required + * PSBT fields (scripts, derivation info) based on the wallet's chain type. + * + * # Arguments + * * `chain` - The chain code (0/1=p2sh, 10/11=p2shP2wsh, 20/21=p2wsh, 30/31=p2tr, 40/41=p2trMusig2) + * * `index` - The derivation index + * * `value` - The value in satoshis + * * `wallet_keys` - The root wallet keys + * + * # Returns + * The index of the newly added output + * @param {number} chain + * @param {number} index + * @param {bigint} value + * @param {WasmRootWalletKeys} wallet_keys + * @returns {number} + */ + add_wallet_output(chain, index, value, wallet_keys) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(wallet_keys, WasmRootWalletKeys); + wasm.bitgopsbt_add_wallet_output(retptr, this.__wbg_ptr, chain, index, value, wallet_keys.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Combine/merge data from another PSBT into this one + * + * This method copies MuSig2 nonces and signatures (proprietary key-value pairs) from the + * source PSBT to this PSBT. This is useful for merging PSBTs during the nonce exchange + * and signature collection phases. + * + * # Arguments + * * `source_psbt` - The source PSBT containing data to merge + * + * # Returns + * Ok(()) if data was successfully merged + * + * # Errors + * Returns error if networks don't match + * @param {BitGoPsbt} source_psbt + */ + combine_musig2_nonces(source_psbt) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(source_psbt, BitGoPsbt); + wasm.bitgopsbt_combine_musig2_nonces(retptr, this.__wbg_ptr, source_psbt.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an empty PSBT for the given network with wallet keys + * + * # Arguments + * * `network` - Network name (utxolib or coin name) + * * `wallet_keys` - The wallet's root keys (used to set global xpubs) + * * `version` - Optional transaction version (default: 2) + * * `lock_time` - Optional lock time (default: 0) + * @param {string} network + * @param {WasmRootWalletKeys} wallet_keys + * @param {number | null} [version] + * @param {number | null} [lock_time] + * @returns {BitGoPsbt} + */ + static create_empty(network, wallet_keys, version, lock_time) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + wasm.bitgopsbt_create_empty(retptr, ptr0, len0, wallet_keys.__wbg_ptr, isLikeNone(version) ? 0x100000001 : (version) >> 0, isLikeNone(lock_time) ? 0x100000001 : (lock_time) >>> 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return BitGoPsbt.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an empty Zcash PSBT with the required consensus branch ID + * + * This method is specifically for Zcash networks which require additional + * parameters for sighash computation. + * + * # Arguments + * * `network` - Network name (must be "zcash" or "zcashTest") + * * `wallet_keys` - The wallet's root keys (used to set global xpubs) + * * `consensus_branch_id` - Zcash consensus branch ID (e.g., 0xC2D6D0B4 for NU5) + * * `version` - Optional transaction version (default: 4 for Zcash Sapling+) + * * `lock_time` - Optional lock time (default: 0) + * * `version_group_id` - Optional version group ID (defaults to Sapling: 0x892F2085) + * * `expiry_height` - Optional expiry height + * @param {string} network + * @param {WasmRootWalletKeys} wallet_keys + * @param {number} consensus_branch_id + * @param {number | null} [version] + * @param {number | null} [lock_time] + * @param {number | null} [version_group_id] + * @param {number | null} [expiry_height] + * @returns {BitGoPsbt} + */ + static create_empty_zcash(network, wallet_keys, consensus_branch_id, version, lock_time, version_group_id, expiry_height) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + wasm.bitgopsbt_create_empty_zcash(retptr, ptr0, len0, wallet_keys.__wbg_ptr, consensus_branch_id, isLikeNone(version) ? 0x100000001 : (version) >> 0, isLikeNone(lock_time) ? 0x100000001 : (lock_time) >>> 0, isLikeNone(version_group_id) ? 0x100000001 : (version_group_id) >>> 0, isLikeNone(expiry_height) ? 0x100000001 : (expiry_height) >>> 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return BitGoPsbt.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an empty Zcash PSBT with consensus branch ID determined from block height + * + * This method automatically determines the correct consensus branch ID based on + * the network and block height using the network upgrade activation heights. + * + * # Arguments + * * `network` - Network name (must be "zcash" or "zcashTest") + * * `wallet_keys` - The wallet's root keys (used to set global xpubs) + * * `block_height` - Block height to determine consensus rules + * * `version` - Optional transaction version (default: 4 for Zcash Sapling+) + * * `lock_time` - Optional lock time (default: 0) + * * `version_group_id` - Optional version group ID (defaults to Sapling: 0x892F2085) + * * `expiry_height` - Optional expiry height + * + * # Errors + * Returns error if block height is before Overwinter activation + * @param {string} network + * @param {WasmRootWalletKeys} wallet_keys + * @param {number} block_height + * @param {number | null} [version] + * @param {number | null} [lock_time] + * @param {number | null} [version_group_id] + * @param {number | null} [expiry_height] + * @returns {BitGoPsbt} + */ + static create_empty_zcash_at_height(network, wallet_keys, block_height, version, lock_time, version_group_id, expiry_height) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + _assertClass(wallet_keys, WasmRootWalletKeys); + wasm.bitgopsbt_create_empty_zcash_at_height(retptr, ptr0, len0, wallet_keys.__wbg_ptr, block_height, isLikeNone(version) ? 0x100000001 : (version) >> 0, isLikeNone(lock_time) ? 0x100000001 : (lock_time) >>> 0, isLikeNone(version_group_id) ? 0x100000001 : (version_group_id) >>> 0, isLikeNone(expiry_height) ? 0x100000001 : (expiry_height) >>> 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return BitGoPsbt.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the Zcash expiry height (returns None for non-Zcash PSBTs) + * @returns {number | undefined} + */ + expiry_height() { + const ret = wasm.bitgopsbt_expiry_height(this.__wbg_ptr); + return ret === 0x100000001 ? undefined : ret; + } + /** + * Extract the final transaction as a WasmTransaction (for BitcoinLike networks) + * + * This avoids re-parsing bytes by returning the transaction directly. + * Only valid for Bitcoin-like networks (not Dash or Zcash). + * @returns {WasmTransaction} + */ + extract_bitcoin_transaction() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_extract_bitcoin_transaction(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Extract the final transaction as a WasmDashTransaction (for Dash networks) + * + * This avoids re-parsing bytes by returning the transaction directly. + * Only valid for Dash networks. + * @returns {WasmDashTransaction} + */ + extract_dash_transaction() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_extract_dash_transaction(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmDashTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Extract a half-signed transaction in legacy format for p2ms-based script types. + * + * This method extracts a transaction where each input has exactly one signature, + * formatted in the legacy style used by utxo-lib and bitcoinjs-lib. The legacy + * format places signatures in the correct position (0, 1, or 2) based on which + * key signed, with empty placeholders for unsigned positions. + * + * # Requirements + * - All inputs must be p2ms-based (p2sh, p2shP2wsh, or p2wsh) + * - Each input must have exactly 1 partial signature + * + * # Returns + * - `Ok(Vec)` containing the serialized half-signed transaction bytes + * - `Err(WasmUtxoError)` if validation fails or extraction fails + * + * # Errors + * - Returns error if any input is not a p2ms type (Taproot, replay protection, etc.) + * - Returns error if any input has 0 or more than 1 partial signature + * @returns {Uint8Array} + */ + extract_half_signed_legacy_tx() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_extract_half_signed_legacy_tx(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Extract the final transaction from a finalized PSBT + * + * This method should be called after all inputs have been finalized. + * It extracts the fully signed transaction as a WASM transaction instance + * appropriate for the network (WasmTransaction, WasmDashTransaction, or WasmZcashTransaction). + * + * # Returns + * - `Ok(JsValue)` containing the WASM transaction instance + * - `Err(WasmUtxoError)` if the PSBT is not fully finalized or extraction fails + * @returns {any} + */ + extract_transaction() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_extract_transaction(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Extract the final transaction as a WasmZcashTransaction (for Zcash networks) + * + * This avoids re-parsing bytes by returning the transaction directly. + * Only valid for Zcash networks. + * @returns {WasmZcashTransaction} + */ + extract_zcash_transaction() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_extract_zcash_transaction(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmZcashTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Finalize all inputs in the PSBT + * + * This method attempts to finalize all inputs in the PSBT, computing the final + * scriptSig and witness data for each input. + * + * # Returns + * - `Ok(())` if all inputs were successfully finalized + * - `Err(WasmUtxoError)` if any input failed to finalize + */ + finalize_all_inputs() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_finalize_all_inputs(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Deserialize a PSBT from bytes with network-specific logic + * @param {Uint8Array} bytes + * @param {string} network + * @returns {BitGoPsbt} + */ + static from_bytes(bytes, network) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.bitgopsbt_from_bytes(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return BitGoPsbt.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Generate and store MuSig2 nonces for all MuSig2 inputs + * + * This method generates nonces using the State-Machine API and stores them in the PSBT. + * The nonces are stored as proprietary fields in the PSBT and will be included when serialized. + * After ALL participants have generated their nonces, they can sign MuSig2 inputs using + * sign_with_xpriv(). + * + * # Arguments + * * `xpriv` - The extended private key (xpriv) for signing + * * `session_id_bytes` - Optional 32-byte session ID for nonce generation. **Only allowed on testnets**. + * On mainnets, a secure random session ID is always generated automatically. + * Must be unique per signing session. + * + * # Returns + * Ok(()) if nonces were successfully generated and stored + * + * # Errors + * Returns error if: + * - Nonce generation fails + * - session_id length is invalid + * - Custom session_id is provided on a mainnet (security restriction) + * + * # Security + * The session_id MUST be cryptographically random and unique for each signing session. + * Never reuse a session_id with the same key! On mainnets, session_id is always randomly + * generated for security. Custom session_id is only allowed on testnets for testing purposes. + * @param {WasmBIP32} xpriv + * @param {Uint8Array | null} [session_id_bytes] + */ + generate_musig2_nonces(xpriv, session_id_bytes) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + var ptr0 = isLikeNone(session_id_bytes) ? 0 : passArray8ToWasm0(session_id_bytes, wasm.__wbindgen_export); + var len0 = WASM_VECTOR_LEN; + wasm.bitgopsbt_generate_musig2_nonces(retptr, this.__wbg_ptr, xpriv.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get all PSBT inputs as an array of PsbtInputData + * + * Returns an array with witness_utxo, bip32_derivation, and tap_bip32_derivation + * for each input. + * @returns {any} + */ + get_inputs() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_get_inputs(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the network type for transaction extraction + * + * Returns "bitcoin", "dash", or "zcash" to indicate which transaction + * wrapper class should be used in TypeScript. + * @returns {string} + */ + get_network_type() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_get_network_type(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } + /** + * Get all PSBT outputs as an array of PsbtOutputData + * + * Returns an array with script, value, bip32_derivation, and tap_bip32_derivation + * for each output. + * @returns {any} + */ + get_outputs() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_get_outputs(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get all PSBT outputs with resolved address strings. + * + * Unlike the generic WrapPsbt which requires a coin parameter, BitGoPsbt + * uses the network it was created/deserialized with to resolve addresses. + * @returns {any} + */ + get_outputs_with_address() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_get_outputs_with_address(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the number of inputs in the PSBT + * @returns {number} + */ + input_count() { + const ret = wasm.bitgopsbt_input_count(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Check if an input is a MuSig2 keypath input. + * + * MuSig2 inputs require special handling: nonces must be generated first with + * `generate_musig2_nonces()`, then signed with `sign_musig2_input()`. + * + * # Arguments + * - `input_index`: The index of the input to check (0-based) + * + * # Returns + * - `true` if the input is a MuSig2 keypath input + * - `false` otherwise (or if input_index is out of bounds) + * @param {number} input_index + * @returns {boolean} + */ + is_musig2_input(input_index) { + const ret = wasm.bitgopsbt_is_musig2_input(this.__wbg_ptr, input_index); + return ret !== 0; + } + /** + * Get the transaction lock time + * @returns {number} + */ + lock_time() { + const ret = wasm.bitgopsbt_lock_time(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Get the network of the PSBT + * @returns {string} + */ + network() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_network(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } + /** + * Get the number of outputs in the PSBT + * @returns {number} + */ + output_count() { + const ret = wasm.bitgopsbt_output_count(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Parse outputs with wallet keys to identify which outputs belong to a wallet + * + * Note: This method does NOT validate wallet inputs. It only parses outputs. + * @param {WasmRootWalletKeys} wallet_keys + * @param {WasmECPair[] | null} [paygo_pubkeys] + * @returns {any} + */ + parse_outputs_with_wallet_keys(wallet_keys, paygo_pubkeys) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(wallet_keys, WasmRootWalletKeys); + var ptr0 = isLikeNone(paygo_pubkeys) ? 0 : passArrayJsValueToWasm0(paygo_pubkeys, wasm.__wbindgen_export); + var len0 = WASM_VECTOR_LEN; + wasm.bitgopsbt_parse_outputs_with_wallet_keys(retptr, this.__wbg_ptr, wallet_keys.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Parse transaction with wallet keys to identify wallet inputs/outputs + * @param {WasmRootWalletKeys} wallet_keys + * @param {WasmReplayProtection} replay_protection + * @param {WasmECPair[] | null} [paygo_pubkeys] + * @returns {any} + */ + parse_transaction_with_wallet_keys(wallet_keys, replay_protection, paygo_pubkeys) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(wallet_keys, WasmRootWalletKeys); + _assertClass(replay_protection, WasmReplayProtection); + var ptr0 = isLikeNone(paygo_pubkeys) ? 0 : passArrayJsValueToWasm0(paygo_pubkeys, wasm.__wbindgen_export); + var len0 = WASM_VECTOR_LEN; + wasm.bitgopsbt_parse_transaction_with_wallet_keys(retptr, this.__wbg_ptr, wallet_keys.__wbg_ptr, replay_protection.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Serialize the PSBT to bytes + * + * # Returns + * The serialized PSBT as a byte array + * @returns {Uint8Array} + */ + serialize() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_serialize(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all MuSig2 keypath inputs in a single pass with optimized sighash computation. + * + * This is more efficient than calling `sign_musig2_input()` for each input because + * it reuses the SighashCache across all inputs, avoiding redundant computation of + * sha_prevouts, sha_amounts, sha_scriptpubkeys, sha_sequences, and sha_outputs. + * + * Each MuSig2 input requires a FirstRound from `generate_musig2_nonces()`. + * FirstRounds that have already been consumed (signed) are skipped. + * + * # Arguments + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + * @param {WasmBIP32} xpriv + * @returns {any} + */ + sign_all_musig2_inputs(xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_all_musig2_inputs(retptr, this.__wbg_ptr, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all replay protection inputs with a raw private key. + * + * This iterates through all inputs looking for P2SH-P2PK (replay protection) inputs + * that match the provided public key and signs them. + * + * # Arguments + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + * @param {WasmECPair} ecpair + * @returns {any} + */ + sign_all_replay_protection_inputs(ecpair) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(ecpair, WasmECPair); + wasm.bitgopsbt_sign_all_replay_protection_inputs(retptr, this.__wbg_ptr, ecpair.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all non-MuSig2 wallet inputs in a single efficient pass. + * + * This signs all ECDSA (P2SH, P2SH-P2WSH, P2WSH) and Taproot script path (P2TR) + * inputs that match the provided xpriv. MuSig2 keypath inputs are skipped. + * + * This is the most efficient way to sign wallet inputs. After calling this, + * sign any MuSig2 inputs using `sign_all_musig2_inputs()` or `sign_musig2_input()`. + * + * # Arguments + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + * @param {WasmBIP32} xpriv + * @returns {any} + */ + sign_all_wallet_inputs(xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_all_wallet_inputs(retptr, this.__wbg_ptr, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all non-MuSig2 inputs with an extended private key (xpriv) in a single pass. + * + * This is more efficient than calling `sign_with_xpriv` for each input individually. + * The underlying miniscript library's `sign` method signs all matching inputs at once. + * + * **Note:** MuSig2 inputs are skipped by this method because they require FirstRound + * state from nonce generation. After calling this method, sign MuSig2 inputs + * individually using `sign_with_xpriv`. + * + * # Arguments + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + * @param {WasmBIP32} xpriv + * @returns {any} + */ + sign_all_with_xpriv(xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_all_wallet_inputs(retptr, this.__wbg_ptr, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a single MuSig2 keypath input. + * + * This uses the FirstRound state generated by `generate_musig2_nonces()`. + * Each FirstRound can only be used once (nonce reuse is a security risk). + * + * For non-MuSig2 inputs, returns an error (use `sign_wallet_input` instead). + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if signing was successful + * - `Err(WasmUtxoError)` if signing fails, no FirstRound exists, or not a MuSig2 input + * @param {number} input_index + * @param {WasmBIP32} xpriv + */ + sign_musig2_input(input_index, xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_musig2_input(retptr, this.__wbg_ptr, input_index, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all replay protection inputs with a raw private key. + * + * This iterates through all inputs looking for P2SH-P2PK (replay protection) inputs + * that match the provided public key and signs them. + * + * # Arguments + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(JsValue)` with an array of input indices that were signed + * - `Err(WasmUtxoError)` if signing fails + * @param {WasmECPair} ecpair + * @returns {any} + */ + sign_replay_protection_inputs(ecpair) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(ecpair, WasmECPair); + wasm.bitgopsbt_sign_all_replay_protection_inputs(retptr, this.__wbg_ptr, ecpair.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a single input with a raw private key, using save/restore for regular inputs. + * + * For replay protection inputs (P2SH-P2PK), this uses direct signing which is + * already single-input. For regular inputs, this clones the PSBT, signs all, + * then copies only the target input's signatures back. + * + * **Important:** This is NOT faster than signing all inputs for regular (non-RP) inputs. + * The underlying miniscript library signs all inputs regardless. + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(())` if the input was signed + * - `Err(WasmUtxoError)` if signing fails + * @param {number} input_index + * @param {WasmECPair} ecpair + */ + sign_single_input_with_privkey(input_index, ecpair) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(ecpair, WasmECPair); + wasm.bitgopsbt_sign_single_input_with_privkey(retptr, this.__wbg_ptr, input_index, ecpair.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a single input with an extended private key, using save/restore for ECDSA inputs. + * + * For MuSig2 inputs, this returns an error (use sign_with_xpriv which handles FirstRound). + * For ECDSA inputs, this clones the PSBT, signs all, then copies only the target + * input's signatures back. + * + * **Important:** This is NOT faster than `sign_all_with_xpriv` for ECDSA inputs. + * The underlying miniscript library signs all inputs regardless. This method + * just prevents signatures from being added to other inputs. + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if the input was signed + * - `Err(WasmUtxoError)` if signing fails + * @param {number} input_index + * @param {WasmBIP32} xpriv + */ + sign_single_input_with_xpriv(input_index, xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_single_input_with_xpriv(retptr, this.__wbg_ptr, input_index, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a single non-MuSig2 wallet input using save/restore pattern. + * + * For MuSig2 inputs, returns an error (use `sign_musig2_input` instead). + * For ECDSA inputs, this uses a save/restore pattern: clones the PSBT, + * signs all inputs on the clone, then copies only the target input's + * signatures back. + * + * **Important:** This is NOT faster than `sign_all_wallet_inputs()` for ECDSA inputs. + * The underlying library signs all inputs regardless. This method just ensures + * that only the specified input gets signatures added to the PSBT. + * Use `sign_all_wallet_inputs()` when signing multiple inputs with the same key. + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if the input was signed + * - `Err(WasmUtxoError)` if signing fails or input is MuSig2 + * @param {number} input_index + * @param {WasmBIP32} xpriv + */ + sign_wallet_input(input_index, xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_single_input_with_xpriv(retptr, this.__wbg_ptr, input_index, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a single input with a raw private key + * + * This method signs a specific input using the provided ECPair. It accepts: + * - A raw privkey (WasmECPair) for replay protection inputs - signs directly + * + * This method automatically detects and handles different input types: + * - For replay protection inputs: signs with legacy P2SH sighash + * - For regular inputs: uses standard PSBT signing + * - For MuSig2 inputs: returns error (requires FirstRound, use sign_with_xpriv instead) + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `ecpair`: The ECPair containing the private key + * + * # Returns + * - `Ok(())` if signing was successful + * - `Err(WasmUtxoError)` if signing fails + * @param {number} input_index + * @param {WasmECPair} ecpair + */ + sign_with_privkey(input_index, ecpair) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(ecpair, WasmECPair); + wasm.bitgopsbt_sign_with_privkey(retptr, this.__wbg_ptr, input_index, ecpair.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a single input with an extended private key (xpriv) + * + * This method signs a specific input using the provided xpriv. It accepts: + * - An xpriv (WasmBIP32) for wallet inputs - derives the key and signs + * + * This method automatically detects and handles different input types: + * - For regular inputs: uses standard PSBT signing + * - For MuSig2 inputs: uses the FirstRound state stored by generate_musig2_nonces() + * - For replay protection inputs: returns error (use sign_with_privkey instead) + * + * # Arguments + * - `input_index`: The index of the input to sign (0-based) + * - `xpriv`: The extended private key as a WasmBIP32 instance + * + * # Returns + * - `Ok(())` if signing was successful + * - `Err(WasmUtxoError)` if signing fails + * @param {number} input_index + * @param {WasmBIP32} xpriv + */ + sign_with_xpriv(input_index, xpriv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpriv, WasmBIP32); + wasm.bitgopsbt_sign_with_xpriv(retptr, this.__wbg_ptr, input_index, xpriv.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the unsigned transaction ID + * @returns {string} + */ + unsigned_txid() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.bitgopsbt_unsigned_txid(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } + /** + * Verify if a replay protection input has a valid signature + * + * This method checks if a given input is a replay protection input and cryptographically verifies + * the signature. Replay protection inputs (like P2shP2pk) don't use standard derivation paths, + * so this method verifies signatures without deriving from xpub. + * + * # Arguments + * - `input_index`: The index of the input to check + * - `replay_protection`: Replay protection configuration (same format as parseTransactionWithWalletKeys) + * Can be either `{ outputScripts: Buffer[] }` or `{ addresses: string[] }` + * + * # Returns + * - `Ok(true)` if the input is a replay protection input and has a valid signature + * - `Ok(false)` if the input is a replay protection input but has no valid signature + * - `Err(WasmUtxoError)` if the input is not a replay protection input, index is out of bounds, or configuration is invalid + * @param {number} input_index + * @param {WasmReplayProtection} replay_protection + * @returns {boolean} + */ + verify_replay_protection_signature(input_index, replay_protection) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(replay_protection, WasmReplayProtection); + wasm.bitgopsbt_verify_replay_protection_signature(retptr, this.__wbg_ptr, input_index, replay_protection.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify if a valid signature exists for a given ECPair key at the specified input index + * + * This method verifies the signature directly with the provided ECPair's public key. It supports: + * - ECDSA signatures (for legacy/SegWit inputs) + * - Schnorr signatures (for Taproot script path inputs) + * + * Note: This method does NOT support MuSig2 inputs, as MuSig2 requires derivation from xpubs. + * Use `verify_signature_with_xpub` for MuSig2 inputs. + * + * # Arguments + * - `input_index`: The index of the input to check + * - `ecpair`: The ECPair key (uses the public key for verification) + * + * # Returns + * - `Ok(true)` if a valid signature exists for the public key + * - `Ok(false)` if no signature exists for the public key + * - `Err(WasmUtxoError)` if the input index is out of bounds or verification fails + * @param {number} input_index + * @param {WasmECPair} ecpair + * @returns {boolean} + */ + verify_signature_with_pub(input_index, ecpair) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(ecpair, WasmECPair); + wasm.bitgopsbt_verify_signature_with_pub(retptr, this.__wbg_ptr, input_index, ecpair.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify if a valid signature exists for a given xpub at the specified input index + * + * This method derives the public key from the xpub using the derivation path found in the + * PSBT input, then verifies the signature. It supports: + * - ECDSA signatures (for legacy/SegWit inputs) + * - Schnorr signatures (for Taproot script path inputs) + * - MuSig2 partial signatures (for Taproot keypath MuSig2 inputs) + * + * # Arguments + * - `input_index`: The index of the input to check + * - `xpub`: The extended public key as a WasmBIP32 instance + * + * # Returns + * - `Ok(true)` if a valid signature exists for the derived public key + * - `Ok(false)` if no signature exists for the derived public key + * - `Err(WasmUtxoError)` if the input index is out of bounds, derivation fails, or verification fails + * @param {number} input_index + * @param {WasmBIP32} xpub + * @returns {boolean} + */ + verify_signature_with_xpub(input_index, xpub) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(xpub, WasmBIP32); + wasm.bitgopsbt_verify_signature_with_xpub(retptr, this.__wbg_ptr, input_index, xpub.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the transaction version + * @returns {number} + */ + version() { + const ret = wasm.bitgopsbt_version(this.__wbg_ptr); + return ret; + } + /** + * Get the Zcash version group ID (returns None for non-Zcash PSBTs) + * @returns {number | undefined} + */ + version_group_id() { + const ret = wasm.bitgopsbt_version_group_id(this.__wbg_ptr); + return ret === 0x100000001 ? undefined : ret; + } +} +if (Symbol.dispose) BitGoPsbt.prototype[Symbol.dispose] = BitGoPsbt.prototype.free; + +export class FixedScriptWalletNamespace { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + FixedScriptWalletNamespaceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_fixedscriptwalletnamespace_free(ptr, 0); + } + /** + * @param {WasmRootWalletKeys} keys + * @param {number} chain + * @param {number} index + * @param {any} network + * @param {string | null} [address_format] + * @returns {string} + */ + static address(keys, chain, index, network, address_format) { + let deferred3_0; + let deferred3_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(keys, WasmRootWalletKeys); + var ptr0 = isLikeNone(address_format) ? 0 : passStringToWasm0(address_format, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len0 = WASM_VECTOR_LEN; + wasm.fixedscriptwalletnamespace_address(retptr, keys.__wbg_ptr, chain, index, addHeapObject(network), ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr2 = r0; + var len2 = r1; + if (r3) { + ptr2 = 0; len2 = 0; + throw takeObject(r2); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred3_0, deferred3_1, 1); + } + } + /** + * @param {WasmRootWalletKeys} keys + * @param {number} chain + * @param {number} index + * @param {string} network + * @param {string | null} [address_format] + * @returns {string} + */ + static address_with_network_str(keys, chain, index, network, address_format) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(keys, WasmRootWalletKeys); + const ptr0 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(address_format) ? 0 : passStringToWasm0(address_format, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.fixedscriptwalletnamespace_address_with_network_str(retptr, keys.__wbg_ptr, chain, index, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1); + } + } + /** + * Get all chain code metadata for building TypeScript lookup tables + * + * Returns an array of [chainCode, scriptType, scope] tuples where: + * - chainCode: u32 (0, 1, 10, 11, 20, 21, 30, 31, 40, 41) + * - scriptType: string ("p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", "p2trMusig2") + * - scope: string ("external" or "internal") + * @returns {any} + */ + static chain_code_table() { + const ret = wasm.fixedscriptwalletnamespace_chain_code_table(); + return takeObject(ret); + } + /** + * Create an OP_RETURN output script with optional data + * + * # Arguments + * * `data` - Optional data bytes to include in the OP_RETURN script + * + * # Returns + * The OP_RETURN script as bytes + * @param {Uint8Array | null} [data] + * @returns {Uint8Array} + */ + static create_op_return_script(data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(data) ? 0 : passArray8ToWasm0(data, wasm.__wbindgen_export); + var len0 = WASM_VECTOR_LEN; + wasm.fixedscriptwalletnamespace_create_op_return_script(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v2 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {WasmRootWalletKeys} keys + * @param {number} chain + * @param {number} index + * @param {any} network + * @returns {Uint8Array} + */ + static output_script(keys, chain, index, network) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(keys, WasmRootWalletKeys); + wasm.fixedscriptwalletnamespace_output_script(retptr, keys.__wbg_ptr, chain, index, addHeapObject(network)); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {WasmRootWalletKeys} keys + * @param {number} chain + * @param {number} index + * @param {string} network + * @returns {Uint8Array} + */ + static output_script_with_network_str(keys, chain, index, network) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(keys, WasmRootWalletKeys); + const ptr0 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.fixedscriptwalletnamespace_output_script_with_network_str(retptr, keys.__wbg_ptr, chain, index, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v2 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the P2SH-P2PK output script for a compressed public key + * + * # Arguments + * * `pubkey` - The compressed public key bytes (33 bytes) + * + * # Returns + * The P2SH-P2PK output script as bytes + * @param {Uint8Array} pubkey + * @returns {Uint8Array} + */ + static p2sh_p2pk_output_script(pubkey) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(pubkey, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.fixedscriptwalletnamespace_p2sh_p2pk_output_script(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v2 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Check if a network supports a given fixed-script wallet script type + * + * # Arguments + * * `coin` - Coin name (e.g., "btc", "ltc", "doge") + * * `script_type` - Script type name: "p2sh", "p2shP2wsh", "p2wsh", "p2tr", "p2trMusig2" + * + * # Returns + * `true` if the network supports the script type, `false` otherwise + * + * # Examples + * - Bitcoin supports all script types (p2sh, p2shP2wsh, p2wsh, p2tr, p2trMusig2) + * - Litecoin supports segwit but not taproot (p2sh, p2shP2wsh, p2wsh) + * - Dogecoin only supports legacy scripts (p2sh) + * @param {string} coin + * @param {string} script_type + * @returns {boolean} + */ + static supports_script_type(coin, script_type) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(coin, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(script_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.fixedscriptwalletnamespace_supports_script_type(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) FixedScriptWalletNamespace.prototype[Symbol.dispose] = FixedScriptWalletNamespace.prototype.free; + +/** + * Namespace for inscription-related functions + */ +export class InscriptionsNamespace { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + InscriptionsNamespaceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_inscriptionsnamespace_free(ptr, 0); + } + /** + * Create inscription reveal data including the commit output script and tap leaf script + * + * # Arguments + * * `x_only_pubkey` - The x-only public key (32 bytes) + * * `content_type` - MIME type of the inscription (e.g., "text/plain", "image/png") + * * `inscription_data` - The inscription data bytes + * + * # Returns + * An object containing: + * - `output_script`: The commit output script (P2TR, network-agnostic) + * - `reveal_transaction_vsize`: Estimated vsize of the reveal transaction + * - `tap_leaf_script`: Object with `leaf_version`, `script`, and `control_block` + * @param {Uint8Array} x_only_pubkey + * @param {string} content_type + * @param {Uint8Array} inscription_data + * @returns {any} + */ + static create_inscription_reveal_data(x_only_pubkey, content_type, inscription_data) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(x_only_pubkey, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(content_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(inscription_data, wasm.__wbindgen_export); + const len2 = WASM_VECTOR_LEN; + wasm.inscriptionsnamespace_create_inscription_reveal_data(retptr, ptr0, len0, ptr1, len1, ptr2, len2); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign a reveal transaction + * + * # Arguments + * * `private_key` - The private key (32 bytes) + * * `tap_leaf_script` - The tap leaf script object from `create_inscription_reveal_data` + * * `commit_tx` - The commit transaction + * * `commit_output_script` - The commit output script (P2TR) + * * `recipient_output_script` - Where to send the inscription (output script) + * * `output_value_sats` - Value in satoshis for the inscription output + * + * # Returns + * The signed PSBT as bytes + * @param {Uint8Array} private_key + * @param {any} tap_leaf_script + * @param {WasmTransaction} commit_tx + * @param {Uint8Array} commit_output_script + * @param {Uint8Array} recipient_output_script + * @param {bigint} output_value_sats + * @returns {Uint8Array} + */ + static sign_reveal_transaction(private_key, tap_leaf_script, commit_tx, commit_output_script, recipient_output_script, output_value_sats) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + _assertClass(commit_tx, WasmTransaction); + const ptr1 = passArray8ToWasm0(commit_output_script, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(recipient_output_script, wasm.__wbindgen_export); + const len2 = WASM_VECTOR_LEN; + wasm.inscriptionsnamespace_sign_reveal_transaction(retptr, ptr0, len0, addHeapObject(tap_leaf_script), commit_tx.__wbg_ptr, ptr1, len1, ptr2, len2, output_value_sats); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v4 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v4; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) InscriptionsNamespace.prototype[Symbol.dispose] = InscriptionsNamespace.prototype.free; + +export class MessageNamespace { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + MessageNamespaceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_messagenamespace_free(ptr, 0); + } + /** + * Sign a message using Bitcoin message signing (BIP-137) + * + * Returns 65-byte signature (1-byte header + 64-byte signature). + * The key must have a private key (cannot sign with public key only). + * @param {WasmECPair} key + * @param {string} message_str + * @returns {Uint8Array} + */ + static sign_message(key, message_str) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(key, WasmECPair); + const ptr0 = passStringToWasm0(message_str, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.messagenamespace_sign_message(retptr, key.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify a Bitcoin message signature (BIP-137) + * + * Signature must be 65 bytes (1-byte header + 64-byte signature). + * Returns true if the signature is valid for this key. + * @param {WasmECPair} key + * @param {string} message_str + * @param {Uint8Array} signature + * @returns {boolean} + */ + static verify_message(key, message_str, signature) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(key, WasmECPair); + const ptr0 = passStringToWasm0(message_str, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(signature, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + wasm.messagenamespace_verify_message(retptr, key.__wbg_ptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) MessageNamespace.prototype[Symbol.dispose] = MessageNamespace.prototype.free; + +export class UtxolibCompatNamespace { + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + UtxolibCompatNamespaceFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_utxolibcompatnamespace_free(ptr, 0); + } + /** + * Convert output script to address string + * + * # Arguments + * * `script` - The output script as a byte array + * * `network` - The UtxolibNetwork object from JavaScript + * * `format` - Optional address format: "default" or "cashaddr" (only applicable for Bitcoin Cash and eCash) + * @param {Uint8Array} script + * @param {any} network + * @param {string | null} [format] + * @returns {string} + */ + static from_output_script(script, network, format) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(format) ? 0 : passStringToWasm0(format, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.utxolibcompatnamespace_from_output_script(retptr, ptr0, len0, addHeapObject(network), ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1); + } + } + /** + * Convert address string to output script + * + * # Arguments + * * `address` - The address string + * * `network` - The UtxolibNetwork object from JavaScript + * * `format` - Optional address format (currently unused for decoding as all formats are accepted) + * @param {string} address + * @param {any} network + * @param {string | null} [format] + * @returns {Uint8Array} + */ + static to_output_script(address, network, format) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(address, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(format) ? 0 : passStringToWasm0(format, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.utxolibcompatnamespace_to_output_script(retptr, ptr0, len0, addHeapObject(network), ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v3 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v3; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) UtxolibCompatNamespace.prototype[Symbol.dispose] = UtxolibCompatNamespace.prototype.free; + +/** + * WASM wrapper for BIP32 extended keys (Xpub/Xpriv) + * Implements the BIP32Interface TypeScript interface + */ +export class WasmBIP32 { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmBIP32.prototype); + obj.__wbg_ptr = ptr; + WasmBIP32Finalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmBIP32Finalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmbip32_free(ptr, 0); + } + /** + * Get the chain code as a Uint8Array + * @returns {Uint8Array} + */ + get chain_code() { + const ret = wasm.wasmbip32_chain_code(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Get the depth + * @returns {number} + */ + get depth() { + const ret = wasm.wasmbip32_depth(this.__wbg_ptr); + return ret; + } + /** + * Derive a normal (non-hardened) child key + * @param {number} index + * @returns {WasmBIP32} + */ + derive(index) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmbip32_derive(retptr, this.__wbg_ptr, index); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Derive a hardened child key (only works for private keys) + * @param {number} index + * @returns {WasmBIP32} + */ + derive_hardened(index) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmbip32_derive_hardened(retptr, this.__wbg_ptr, index); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Derive a key using a derivation path (e.g., "0/1/2" or "m/0/1/2") + * @param {string} path + * @returns {WasmBIP32} + */ + derive_path(path) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(path, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmbip32_derive_path(retptr, this.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Check equality with another WasmBIP32 key. + * Two keys are equal if they have the same type (public/private) and identical + * BIP32 metadata (depth, parent fingerprint, child index, chain code, key data). + * @param {WasmBIP32} other + * @returns {boolean} + */ + equals(other) { + _assertClass(other, WasmBIP32); + const ret = wasm.wasmbip32_equals(this.__wbg_ptr, other.__wbg_ptr); + return ret !== 0; + } + /** + * Get the fingerprint as a Uint8Array + * @returns {Uint8Array} + */ + get fingerprint() { + const ret = wasm.wasmbip32_fingerprint(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Create a BIP32 key from a base58 string (xpub/xprv/tpub/tprv) + * @param {string} base58_str + * @returns {WasmBIP32} + */ + static from_base58(base58_str) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(base58_str, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmbip32_from_base58(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a BIP32 key from a BIP32Interface JavaScript object properties + * Expects an object with: network.bip32.public, depth, parentFingerprint, + * index, chainCode, and publicKey properties + * @param {any} bip32_key + * @returns {WasmBIP32} + */ + static from_bip32_interface(bip32_key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmbip32_from_bip32_interface(retptr, addBorrowedObject(bip32_key)); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + heap[stack_pointer++] = undefined; + } + } + /** + * Create a BIP32 key from BIP32 properties + * Extracts properties from a JavaScript object and constructs an xpub or xprv + * @param {any} bip32_key + * @returns {WasmBIP32} + */ + static from_bip32_properties(bip32_key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmbip32_from_bip32_interface(retptr, addBorrowedObject(bip32_key)); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + heap[stack_pointer++] = undefined; + } + } + /** + * Create a BIP32 master key from a seed + * @param {Uint8Array} seed + * @param {string | null} [network] + * @returns {WasmBIP32} + */ + static from_seed(seed, network) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(seed, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(network) ? 0 : passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.wasmbip32_from_seed(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a BIP32 master key from a string by hashing it with SHA256. + * This is useful for deterministic test key generation. + * @param {string} seed_string + * @param {string | null} [network] + * @returns {WasmBIP32} + */ + static from_seed_sha256(seed_string, network) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(seed_string, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(network) ? 0 : passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.wasmbip32_from_seed_sha256(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a BIP32 key from an xprv string (base58-encoded) + * @param {string} xprv_str + * @returns {WasmBIP32} + */ + static from_xprv(xprv_str) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(xprv_str, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmbip32_from_xprv(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create a BIP32 key from an xpub string (base58-encoded) + * @param {string} xpub_str + * @returns {WasmBIP32} + */ + static from_xpub(xpub_str) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(xpub_str, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmbip32_from_xpub(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmBIP32.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the identifier as a Uint8Array + * @returns {Uint8Array} + */ + get identifier() { + const ret = wasm.wasmbip32_identifier(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Get the child index + * @returns {number} + */ + get index() { + const ret = wasm.wasmbip32_index(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Check if this is a neutered (public) key + * @returns {boolean} + */ + is_neutered() { + const ret = wasm.wasmbip32_is_neutered(this.__wbg_ptr); + return ret !== 0; + } + /** + * Get the neutered (public) version of this key + * @returns {WasmBIP32} + */ + neutered() { + const ret = wasm.wasmbip32_neutered(this.__wbg_ptr); + return WasmBIP32.__wrap(ret); + } + /** + * Get the parent fingerprint + * @returns {number} + */ + get parent_fingerprint() { + const ret = wasm.wasmbip32_parent_fingerprint(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Get the private key as a Uint8Array (if available) + * @returns {Uint8Array | undefined} + */ + get private_key() { + const ret = wasm.wasmbip32_private_key(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Get the public key as a Uint8Array + * @returns {Uint8Array} + */ + get public_key() { + const ret = wasm.wasmbip32_public_key(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Serialize to base58 string + * @returns {string} + */ + to_base58() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmbip32_to_base58(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } + /** + * Get the WIF encoding of the private key + * @returns {string} + */ + to_wif() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmbip32_to_wif(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } +} +if (Symbol.dispose) WasmBIP32.prototype[Symbol.dispose] = WasmBIP32.prototype.free; + +/** + * Dash transaction wrapper that supports Dash special transactions (EVO) by preserving extra payload. + */ +export class WasmDashTransaction { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmDashTransaction.prototype); + obj.__wbg_ptr = ptr; + WasmDashTransactionFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmDashTransactionFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmdashtransaction_free(ptr, 0); + } + /** + * Deserialize a Dash transaction from bytes (supports EVO special tx extra payload). + * @param {Uint8Array} bytes + * @returns {WasmDashTransaction} + */ + static from_bytes(bytes) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wasmdashtransaction_from_bytes(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmDashTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the transaction ID (txid) + * + * The txid is the double SHA256 of the full Dash transaction bytes, + * displayed in reverse byte order (big-endian) as is standard. + * + * # Returns + * The transaction ID as a hex string + * + * # Errors + * Returns an error if the transaction cannot be serialized + * @returns {string} + */ + get_txid() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmdashtransaction_get_txid(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } + /** + * Serialize the Dash transaction to bytes (preserving tx_type and extra payload). + * @returns {Uint8Array} + */ + to_bytes() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmdashtransaction_to_bytes(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) WasmDashTransaction.prototype[Symbol.dispose] = WasmDashTransaction.prototype.free; + +/** + * Dimensions for estimating transaction virtual size. + * + * Tracks weight internally with min/max bounds to handle ECDSA signature variance. + * Schnorr signatures have no variance (always 64 bytes). + */ +export class WasmDimensions { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmDimensions.prototype); + obj.__wbg_ptr = ptr; + WasmDimensionsFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmDimensionsFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmdimensions_free(ptr, 0); + } + /** + * Create empty dimensions (zero weight) + * @returns {WasmDimensions} + */ + static empty() { + const ret = wasm.wasmdimensions_empty(); + return WasmDimensions.__wrap(ret); + } + /** + * Create dimensions for a single input from chain code + * + * # Arguments + * * `chain` - Chain code (0/1=p2sh, 10/11=p2shP2wsh, 20/21=p2wsh, 30/31=p2tr, 40/41=p2trMusig2) + * * `signer` - Optional signer key ("user", "backup", "bitgo") + * * `cosigner` - Optional cosigner key ("user", "backup", "bitgo") + * * `compat` - When true, use 72-byte signatures for max (matches @bitgo/unspents) + * @param {number} chain + * @param {string | null} [signer] + * @param {string | null} [cosigner] + * @param {boolean | null} [compat] + * @returns {WasmDimensions} + */ + static from_input(chain, signer, cosigner, compat) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(signer) ? 0 : passStringToWasm0(signer, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(cosigner) ? 0 : passStringToWasm0(cosigner, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.wasmdimensions_from_input(retptr, chain, ptr0, len0, ptr1, len1, isLikeNone(compat) ? 0xFFFFFF : compat ? 1 : 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmDimensions.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create dimensions for a single input from script type string + * + * # Arguments + * * `script_type` - One of: "p2sh", "p2shP2wsh", "p2wsh", "p2trLegacy", + * "p2trMusig2KeyPath", "p2trMusig2ScriptPath", "p2shP2pk" + * * `compat` - When true, use 72-byte signatures for max (matches @bitgo/unspents) + * @param {string} script_type + * @param {boolean | null} [compat] + * @returns {WasmDimensions} + */ + static from_input_script_type(script_type, compat) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(script_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmdimensions_from_input_script_type(retptr, ptr0, len0, isLikeNone(compat) ? 0xFFFFFF : compat ? 1 : 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmDimensions.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create dimensions for a single output from script length + * @param {number} length + * @returns {WasmDimensions} + */ + static from_output_script_length(length) { + const ret = wasm.wasmdimensions_from_output_script_length(length); + return WasmDimensions.__wrap(ret); + } + /** + * Create dimensions for a single output from script type string + * + * # Arguments + * * `script_type` - One of: "p2sh", "p2shP2wsh", "p2wsh", "p2tr"/"p2trLegacy", "p2trMusig2" + * @param {string} script_type + * @returns {WasmDimensions} + */ + static from_output_script_type(script_type) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(script_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmdimensions_from_output_script_type(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmDimensions.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create dimensions from a BitGoPsbt + * + * Parses PSBT inputs and outputs to compute weight bounds without + * requiring wallet keys. Input types are detected from BIP32 derivation + * paths stored in the PSBT. + * @param {BitGoPsbt} psbt + * @returns {WasmDimensions} + */ + static from_psbt(psbt) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(psbt, BitGoPsbt); + wasm.wasmdimensions_from_psbt(retptr, psbt.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmDimensions.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get input virtual size (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + * @param {string | null} [size] + * @returns {number} + */ + get_input_vsize(size) { + var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.wasmdimensions_get_input_vsize(this.__wbg_ptr, ptr0, len0); + return ret >>> 0; + } + /** + * Get input weight only (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + * @param {string | null} [size] + * @returns {number} + */ + get_input_weight(size) { + var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.wasmdimensions_get_input_weight(this.__wbg_ptr, ptr0, len0); + return ret >>> 0; + } + /** + * Get output virtual size + * @returns {number} + */ + get_output_vsize() { + const ret = wasm.wasmdimensions_get_output_vsize(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Get output weight + * @returns {number} + */ + get_output_weight() { + const ret = wasm.wasmdimensions_get_output_weight(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Get virtual size (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + * @param {string | null} [size] + * @returns {number} + */ + get_vsize(size) { + var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.wasmdimensions_get_vsize(this.__wbg_ptr, ptr0, len0); + return ret >>> 0; + } + /** + * Get total weight (min or max) + * + * # Arguments + * * `size` - "min" or "max", defaults to "max" + * @param {string | null} [size] + * @returns {number} + */ + get_weight(size) { + var ptr0 = isLikeNone(size) ? 0 : passStringToWasm0(size, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.wasmdimensions_get_weight(this.__wbg_ptr, ptr0, len0); + return ret >>> 0; + } + /** + * Whether any inputs are segwit (affects overhead calculation) + * @returns {boolean} + */ + has_segwit() { + const ret = wasm.wasmdimensions_has_segwit(this.__wbg_ptr); + return ret !== 0; + } + /** + * Combine with another Dimensions instance + * @param {WasmDimensions} other + * @returns {WasmDimensions} + */ + plus(other) { + _assertClass(other, WasmDimensions); + const ret = wasm.wasmdimensions_plus(this.__wbg_ptr, other.__wbg_ptr); + return WasmDimensions.__wrap(ret); + } + /** + * Multiply dimensions by a scalar + * @param {number} n + * @returns {WasmDimensions} + */ + times(n) { + const ret = wasm.wasmdimensions_times(this.__wbg_ptr, n); + return WasmDimensions.__wrap(ret); + } +} +if (Symbol.dispose) WasmDimensions.prototype[Symbol.dispose] = WasmDimensions.prototype.free; + +/** + * WASM wrapper for elliptic curve key pairs (always uses compressed keys) + */ +export class WasmECPair { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmECPair.prototype); + obj.__wbg_ptr = ptr; + WasmECPairFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + static __unwrap(jsValue) { + if (!(jsValue instanceof WasmECPair)) { + return 0; + } + return jsValue.__destroy_into_raw(); + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmECPairFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmecpair_free(ptr, 0); + } + /** + * Create an ECPair from a private key (always uses compressed keys) + * @param {Uint8Array} private_key + * @returns {WasmECPair} + */ + static from_private_key(private_key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wasmecpair_from_private_key(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmECPair.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an ECPair from a public key (always uses compressed keys) + * @param {Uint8Array} public_key + * @returns {WasmECPair} + */ + static from_public_key(public_key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(public_key, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wasmecpair_from_public_key(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmECPair.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an ECPair from a WIF string (auto-detects network) + * @param {string} wif_string + * @returns {WasmECPair} + */ + static from_wif(wif_string) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(wif_string, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmecpair_from_wif(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmECPair.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an ECPair from a mainnet WIF string + * @param {string} wif_string + * @returns {WasmECPair} + */ + static from_wif_mainnet(wif_string) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(wif_string, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmecpair_from_wif_mainnet(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmECPair.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create an ECPair from a testnet WIF string + * @param {string} wif_string + * @returns {WasmECPair} + */ + static from_wif_testnet(wif_string) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(wif_string, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmecpair_from_wif_testnet(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmECPair.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the private key as a Uint8Array (if available) + * @returns {Uint8Array | undefined} + */ + get private_key() { + const ret = wasm.wasmecpair_private_key(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Get the compressed public key as a Uint8Array (always 33 bytes) + * @returns {Uint8Array} + */ + get public_key() { + const ret = wasm.wasmecpair_public_key(this.__wbg_ptr); + return takeObject(ret); + } + /** + * Convert to WIF string (mainnet) + * @returns {string} + */ + to_wif() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmecpair_to_wif(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } + /** + * Convert to mainnet WIF string + * @returns {string} + */ + to_wif_mainnet() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmecpair_to_wif_mainnet(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } + /** + * Convert to testnet WIF string + * @returns {string} + */ + to_wif_testnet() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmecpair_to_wif_testnet(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } +} +if (Symbol.dispose) WasmECPair.prototype[Symbol.dispose] = WasmECPair.prototype.free; + +/** + * WASM wrapper for ReplayProtection + */ +export class WasmReplayProtection { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmReplayProtection.prototype); + obj.__wbg_ptr = ptr; + WasmReplayProtectionFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmReplayProtectionFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmreplayprotection_free(ptr, 0); + } + /** + * Create from addresses (requires network for decoding) + * @param {any[]} addresses + * @param {string} network + * @returns {WasmReplayProtection} + */ + static from_addresses(addresses, network) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArrayJsValueToWasm0(addresses, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(network, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.wasmreplayprotection_from_addresses(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmReplayProtection.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Create from output scripts directly + * @param {Uint8Array[]} output_scripts + * @returns {WasmReplayProtection} + */ + static from_output_scripts(output_scripts) { + const ptr0 = passArrayJsValueToWasm0(output_scripts, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.wasmreplayprotection_from_output_scripts(ptr0, len0); + return WasmReplayProtection.__wrap(ret); + } + /** + * Create from public keys (derives P2SH-P2PK output scripts) + * @param {Uint8Array[]} public_keys + * @returns {WasmReplayProtection} + */ + static from_public_keys(public_keys) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArrayJsValueToWasm0(public_keys, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wasmreplayprotection_from_public_keys(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmReplayProtection.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) WasmReplayProtection.prototype[Symbol.dispose] = WasmReplayProtection.prototype.free; + +/** + * WASM wrapper for RootWalletKeys + * Represents a set of three extended public keys with their derivation prefixes + */ +export class WasmRootWalletKeys { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmRootWalletKeys.prototype); + obj.__wbg_ptr = ptr; + WasmRootWalletKeysFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmRootWalletKeysFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmrootwalletkeys_free(ptr, 0); + } + /** + * Get the backup key (second xpub) + * @returns {WasmBIP32} + */ + backup_key() { + const ret = wasm.wasmrootwalletkeys_backup_key(this.__wbg_ptr); + return WasmBIP32.__wrap(ret); + } + /** + * Get the bitgo key (third xpub) + * @returns {WasmBIP32} + */ + bitgo_key() { + const ret = wasm.wasmrootwalletkeys_bitgo_key(this.__wbg_ptr); + return WasmBIP32.__wrap(ret); + } + /** + * Create a RootWalletKeys from three BIP32 keys + * Uses default derivation prefix of m/0/0 for all three keys + * + * # Arguments + * - `user`: User key (first xpub) + * - `backup`: Backup key (second xpub) + * - `bitgo`: BitGo key (third xpub) + * @param {WasmBIP32} user + * @param {WasmBIP32} backup + * @param {WasmBIP32} bitgo + */ + constructor(user, backup, bitgo) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(user, WasmBIP32); + _assertClass(backup, WasmBIP32); + _assertClass(bitgo, WasmBIP32); + wasm.wasmrootwalletkeys_new(retptr, user.__wbg_ptr, backup.__wbg_ptr, bitgo.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + this.__wbg_ptr = r0 >>> 0; + WasmRootWalletKeysFinalization.register(this, this.__wbg_ptr, this); + return this; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the user key (first xpub) + * @returns {WasmBIP32} + */ + user_key() { + const ret = wasm.wasmrootwalletkeys_user_key(this.__wbg_ptr); + return WasmBIP32.__wrap(ret); + } + /** + * Create a RootWalletKeys from three BIP32 keys with custom derivation prefixes + * + * # Arguments + * - `user`: User key (first xpub) + * - `backup`: Backup key (second xpub) + * - `bitgo`: BitGo key (third xpub) + * - `user_derivation`: Derivation path for user key (e.g., "m/0/0") + * - `backup_derivation`: Derivation path for backup key (e.g., "m/0/0") + * - `bitgo_derivation`: Derivation path for bitgo key (e.g., "m/0/0") + * @param {WasmBIP32} user + * @param {WasmBIP32} backup + * @param {WasmBIP32} bitgo + * @param {string} user_derivation + * @param {string} backup_derivation + * @param {string} bitgo_derivation + * @returns {WasmRootWalletKeys} + */ + static with_derivation_prefixes(user, backup, bitgo, user_derivation, backup_derivation, bitgo_derivation) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(user, WasmBIP32); + _assertClass(backup, WasmBIP32); + _assertClass(bitgo, WasmBIP32); + const ptr0 = passStringToWasm0(user_derivation, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(backup_derivation, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passStringToWasm0(bitgo_derivation, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len2 = WASM_VECTOR_LEN; + wasm.wasmrootwalletkeys_with_derivation_prefixes(retptr, user.__wbg_ptr, backup.__wbg_ptr, bitgo.__wbg_ptr, ptr0, len0, ptr1, len1, ptr2, len2); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmRootWalletKeys.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) WasmRootWalletKeys.prototype[Symbol.dispose] = WasmRootWalletKeys.prototype.free; + +/** + * A Bitcoin-like transaction (for all networks except Zcash) + * + * This class provides basic transaction parsing and serialization for testing + * compatibility with third-party transaction fixtures. + */ +export class WasmTransaction { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmTransaction.prototype); + obj.__wbg_ptr = ptr; + WasmTransactionFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmTransactionFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmtransaction_free(ptr, 0); + } + /** + * Add an input to the transaction + * + * # Arguments + * * `txid` - The transaction ID (hex string) of the output being spent + * * `vout` - The output index being spent + * * `sequence` - Optional sequence number (default: 0xFFFFFFFF) + * + * # Returns + * The index of the newly added input + * @param {string} txid + * @param {number} vout + * @param {number | null} [sequence] + * @returns {number} + */ + add_input(txid, vout, sequence) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(txid, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wasmtransaction_add_input(retptr, this.__wbg_ptr, ptr0, len0, vout, isLikeNone(sequence) ? 0x100000001 : (sequence) >>> 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add an output to the transaction + * + * # Arguments + * * `script` - The output script (scriptPubKey) + * * `value` - The value in satoshis + * + * # Returns + * The index of the newly added output + * @param {Uint8Array} script + * @param {bigint} value + * @returns {number} + */ + add_output(script, value) { + const ptr0 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.wasmtransaction_add_output(this.__wbg_ptr, ptr0, len0, value); + return ret >>> 0; + } + /** + * Create an empty transaction (version 1, locktime 0) + * @returns {WasmTransaction} + */ + static create() { + const ret = wasm.wasmtransaction_create(); + return WasmTransaction.__wrap(ret); + } + /** + * Deserialize a transaction from bytes + * + * # Arguments + * * `bytes` - The serialized transaction bytes + * + * # Returns + * A WasmTransaction instance + * + * # Errors + * Returns an error if the bytes cannot be parsed as a valid transaction + * @param {Uint8Array} bytes + * @returns {WasmTransaction} + */ + static from_bytes(bytes) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wasmtransaction_from_bytes(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the transaction ID (txid) + * + * The txid is the double SHA256 of the transaction bytes (excluding witness + * data for segwit transactions), displayed in reverse byte order (big-endian) + * as is standard for Bitcoin. + * + * # Returns + * The transaction ID as a hex string + * @returns {string} + */ + get_txid() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmtransaction_get_txid(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } + /** + * Get the virtual size of the transaction + * + * Virtual size is calculated as ceil(weight / 4), where weight accounts + * for the segwit discount on witness data. + * + * # Returns + * The virtual size in virtual bytes (vbytes) + * @returns {number} + */ + get_vsize() { + const ret = wasm.wasmtransaction_get_vsize(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Serialize the transaction to bytes + * + * # Returns + * The serialized transaction bytes + * @returns {Uint8Array} + */ + to_bytes() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmtransaction_to_bytes(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) WasmTransaction.prototype[Symbol.dispose] = WasmTransaction.prototype.free; + +/** + * A Zcash transaction with network-specific fields + * + * This class provides basic transaction parsing and serialization for Zcash + * transactions, which use the Overwinter transaction format. + */ +export class WasmZcashTransaction { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WasmZcashTransaction.prototype); + obj.__wbg_ptr = ptr; + WasmZcashTransactionFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WasmZcashTransactionFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wasmzcashtransaction_free(ptr, 0); + } + /** + * Deserialize a Zcash transaction from bytes + * + * # Arguments + * * `bytes` - The serialized transaction bytes + * + * # Returns + * A WasmZcashTransaction instance + * + * # Errors + * Returns an error if the bytes cannot be parsed as a valid Zcash transaction + * @param {Uint8Array} bytes + * @returns {WasmZcashTransaction} + */ + static from_bytes(bytes) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wasmzcashtransaction_from_bytes(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmZcashTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the transaction ID (txid) + * + * The txid is the double SHA256 of the full Zcash transaction bytes, + * displayed in reverse byte order (big-endian) as is standard. + * + * # Returns + * The transaction ID as a hex string + * + * # Errors + * Returns an error if the transaction cannot be serialized + * @returns {string} + */ + get_txid() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmzcashtransaction_get_txid(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } + /** + * Serialize the transaction to bytes + * + * # Returns + * The serialized transaction bytes + * @returns {Uint8Array} + */ + to_bytes() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wasmzcashtransaction_to_bytes(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } +} +if (Symbol.dispose) WasmZcashTransaction.prototype[Symbol.dispose] = WasmZcashTransaction.prototype.free; + +export class WrapDescriptor { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WrapDescriptor.prototype); + obj.__wbg_ptr = ptr; + WrapDescriptorFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WrapDescriptorFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wrapdescriptor_free(ptr, 0); + } + /** + * @param {number} index + * @returns {WrapDescriptor} + */ + atDerivationIndex(index) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_atDerivationIndex(retptr, this.__wbg_ptr, index); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WrapDescriptor.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {any} + */ + descType() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_descType(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {Uint8Array} + */ + encode() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_encode(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Parse a descriptor string with an explicit public key type. + * + * Note that this function permits parsing a non-derivable descriptor with a derivable key type. + * Use `from_string_detect_type` to automatically detect the key type. + * + * # Arguments + * * `descriptor` - A string containing the descriptor to parse + * * `pk_type` - The type of public key to expect: + * - "derivable": For descriptors containing derivation paths (eg. xpubs) + * - "definite": For descriptors with fully specified keys + * - "string": For descriptors with string placeholders + * + * # Returns + * * `Result` - The parsed descriptor or an error + * + * # Example + * ``` + * use wasm_utxo::WrapDescriptor; + * let desc = WrapDescriptor::from_string( + * "pk(xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8/*)", + * "derivable" + * ); + * ``` + * @param {string} descriptor + * @param {string} pk_type + * @returns {WrapDescriptor} + */ + static fromString(descriptor, pk_type) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(descriptor, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(pk_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.wrapdescriptor_fromString(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WrapDescriptor.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Parse a descriptor string, automatically detecting the appropriate public key type. + * This will check if the descriptor contains wildcards to determine if it should be + * parsed as derivable or definite. + * + * # Arguments + * * `descriptor` - A string containing the descriptor to parse + * + * # Returns + * * `Result` - The parsed descriptor or an error + * + * # Example + * ``` + * use wasm_utxo::WrapDescriptor; + * // Will be parsed as definite since it has no wildcards + * let desc = WrapDescriptor::from_string_detect_type( + * "pk(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)" + * ); + * + * // Will be parsed as derivable since it contains a wildcard (*) + * let desc = WrapDescriptor::from_string_detect_type( + * "pk(xpub.../0/*)" + * ); + * ``` + * @param {string} descriptor + * @returns {WrapDescriptor} + */ + static fromStringDetectType(descriptor) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(descriptor, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wrapdescriptor_fromStringDetectType(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WrapDescriptor.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {boolean} + */ + hasWildcard() { + const ret = wasm.wrapdescriptor_hasWildcard(this.__wbg_ptr); + return ret !== 0; + } + /** + * @returns {number} + */ + maxWeightToSatisfy() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_maxWeightToSatisfy(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {any} + */ + node() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_node(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {Uint8Array} + */ + scriptPubkey() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_scriptPubkey(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + if (r3) { + throw takeObject(r2); + } + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {string} + */ + toAsmString() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_toAsmString(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } + /** + * @returns {string} + */ + toString() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapdescriptor_toString(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } +} +if (Symbol.dispose) WrapDescriptor.prototype[Symbol.dispose] = WrapDescriptor.prototype.free; + +export class WrapMiniscript { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WrapMiniscript.prototype); + obj.__wbg_ptr = ptr; + WrapMiniscriptFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WrapMiniscriptFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wrapminiscript_free(ptr, 0); + } + /** + * @returns {Uint8Array} + */ + encode() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapminiscript_encode(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {Uint8Array} script + * @param {string} context_type + * @returns {WrapMiniscript} + */ + static fromBitcoinScript(script, context_type) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(context_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.wrapminiscript_fromBitcoinScript(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WrapMiniscript.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {string} script + * @param {string} context_type + * @returns {WrapMiniscript} + */ + static fromString(script, context_type) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(script, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(context_type, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.wrapminiscript_fromString(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WrapMiniscript.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {any} + */ + node() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapminiscript_node(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {string} + */ + toAsmString() { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapminiscript_toAsmString(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr1 = r0; + var len1 = r1; + if (r3) { + ptr1 = 0; len1 = 0; + throw takeObject(r2); + } + deferred2_0 = ptr1; + deferred2_1 = len1; + return getStringFromWasm0(ptr1, len1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1); + } + } + /** + * @returns {string} + */ + toString() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrapminiscript_toString(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } +} +if (Symbol.dispose) WrapMiniscript.prototype[Symbol.dispose] = WrapMiniscript.prototype.free; + +export class WrapPsbt { + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(WrapPsbt.prototype); + obj.__wbg_ptr = ptr; + WrapPsbtFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + WrapPsbtFinalization.unregister(this); + return ptr; + } + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_wrappsbt_free(ptr, 0); + } + /** + * Add an input to the PSBT + * + * # Arguments + * * `txid` - Transaction ID (hex string, 32 bytes reversed) + * * `vout` - Output index being spent + * * `value` - Value in satoshis of the output being spent + * * `script` - The scriptPubKey of the output being spent + * * `sequence` - Sequence number (default: 0xFFFFFFFE for RBF) + * + * # Returns + * The index of the newly added input + * @param {string} txid + * @param {number} vout + * @param {bigint} value + * @param {Uint8Array} script + * @param {number | null} [sequence] + * @returns {number} + */ + addInput(txid, vout, value, script, sequence) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(txid, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len1 = WASM_VECTOR_LEN; + wasm.wrappsbt_addInput(retptr, this.__wbg_ptr, ptr0, len0, vout, value, ptr1, len1, isLikeNone(sequence) ? 0x100000001 : (sequence) >>> 0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Add an output to the PSBT + * + * # Arguments + * * `script` - The output script (scriptPubKey) + * * `value` - Value in satoshis + * + * # Returns + * The index of the newly added output + * @param {Uint8Array} script + * @param {bigint} value + * @returns {number} + */ + addOutput(script, value) { + const ptr0 = passArray8ToWasm0(script, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.wrappsbt_addOutput(this.__wbg_ptr, ptr0, len0, value); + return ret >>> 0; + } + /** + * @returns {WrapPsbt} + */ + clone() { + const ret = wasm.wrappsbt_clone(this.__wbg_ptr); + return WrapPsbt.__wrap(ret); + } + /** + * @param {Uint8Array} psbt + * @returns {WrapPsbt} + */ + static deserialize(psbt) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(psbt, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wrappsbt_deserialize(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WrapPsbt.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Extract the final transaction from a finalized PSBT + * + * This method should be called after all inputs have been finalized. + * It extracts the fully signed transaction as a WasmTransaction instance. + * + * # Returns + * - `Ok(WasmTransaction)` containing the extracted transaction + * - `Err(WasmUtxoError)` if the PSBT is not fully finalized or extraction fails + * @returns {WasmTransaction} + */ + extractTransaction() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_extractTransaction(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return WasmTransaction.__wrap(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + finalize() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_finalize(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get all PSBT inputs as an array of PsbtInputData + * + * Returns an array with witness_utxo, bip32_derivation, and tap_bip32_derivation + * for each input. This is useful for introspecting the PSBT structure. + * @returns {any} + */ + getInputs() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_getInputs(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get all PSBT outputs as an array of PsbtOutputData + * + * Returns an array with script, value, bip32_derivation, and tap_bip32_derivation + * for each output. This is useful for introspecting the PSBT structure. + * @returns {any} + */ + getOutputs() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_getOutputs(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get all PSBT outputs with resolved address strings. + * + * Like `getOutputs()` but each element also includes an `address` field + * derived from the output script using the given coin name (e.g. "btc", "tbtc"). + * @param {string} coin + * @returns {any} + */ + getOutputsWithAddress(coin) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(coin, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wrappsbt_getOutputsWithAddress(retptr, this.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get partial signatures for an input + * Returns array of { pubkey: Uint8Array, signature: Uint8Array } + * @param {number} input_index + * @returns {any} + */ + getPartialSignatures(input_index) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_getPartialSignatures(retptr, this.__wbg_ptr, input_index); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the unsigned transaction bytes + * + * # Returns + * The serialized unsigned transaction + * @returns {Uint8Array} + */ + getUnsignedTx() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_getUnsignedTx(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Check if an input has any partial signatures + * @param {number} input_index + * @returns {boolean} + */ + hasPartialSignatures(input_index) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_hasPartialSignatures(retptr, this.__wbg_ptr, input_index); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the number of inputs in the PSBT + * @returns {number} + */ + inputCount() { + const ret = wasm.wrappsbt_inputCount(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Get the transaction lock time + * @returns {number} + */ + lockTime() { + const ret = wasm.wrappsbt_lockTime(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Create an empty PSBT + * + * # Arguments + * * `version` - Transaction version (default: 2) + * * `lock_time` - Transaction lock time (default: 0) + * @param {number | null} [version] + * @param {number | null} [lock_time] + */ + constructor(version, lock_time) { + const ret = wasm.wrappsbt_new(isLikeNone(version) ? 0x100000001 : (version) >> 0, isLikeNone(lock_time) ? 0x100000001 : (lock_time) >>> 0); + this.__wbg_ptr = ret >>> 0; + WrapPsbtFinalization.register(this, this.__wbg_ptr, this); + return this; + } + /** + * Get the number of outputs in the PSBT + * @returns {number} + */ + outputCount() { + const ret = wasm.wrappsbt_outputCount(this.__wbg_ptr); + return ret >>> 0; + } + /** + * Remove an output from the PSBT by index. + * + * Removes both the transaction output and the PSBT output metadata. + * @param {number} index + */ + removeOutput(index) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_removeOutput(retptr, this.__wbg_ptr, index); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @returns {Uint8Array} + */ + serialize() { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_serialize(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var v1 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_export4(r0, r1 * 1, 1); + return v1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all inputs with a WasmBIP32 key + * + * This method signs all inputs that match the BIP32 derivation paths in the PSBT. + * Returns a map of input indices to the public keys that were signed. + * + * # Arguments + * * `key` - The WasmBIP32 key to sign with + * + * # Returns + * A SigningKeysMap converted to JsValue (object mapping input indices to signing keys) + * @param {WasmBIP32} key + * @returns {any} + */ + signAll(key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(key, WasmBIP32); + wasm.wrappsbt_signAll(retptr, this.__wbg_ptr, key.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Sign all inputs with a WasmECPair key + * + * This method signs all inputs using the private key from the ECPair. + * Returns a map of input indices to the public keys that were signed. + * + * # Arguments + * * `key` - The WasmECPair key to sign with + * + * # Returns + * A SigningKeysMap converted to JsValue (object mapping input indices to signing keys) + * @param {WasmECPair} key + * @returns {any} + */ + signAllWithEcpair(key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(key, WasmECPair); + wasm.wrappsbt_signAllWithEcpair(retptr, this.__wbg_ptr, key.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {Uint8Array} prv + * @returns {any} + */ + signWithPrv(prv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(prv, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wrappsbt_signWithPrv(retptr, this.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {string} xprv + * @returns {any} + */ + signWithXprv(xprv) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(xprv, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + wasm.wrappsbt_signWithXprv(retptr, this.__wbg_ptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return takeObject(r0); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the unsigned transaction ID as a hex string + * @returns {string} + */ + unsignedTxId() { + let deferred1_0; + let deferred1_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.wrappsbt_unsignedTxId(retptr, this.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred1_0 = r0; + deferred1_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred1_0, deferred1_1, 1); + } + } + /** + * @param {number} input_index + * @param {WrapDescriptor} descriptor + */ + updateInputWithDescriptor(input_index, descriptor) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(descriptor, WrapDescriptor); + wasm.wrappsbt_updateInputWithDescriptor(retptr, this.__wbg_ptr, input_index, descriptor.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * @param {number} output_index + * @param {WrapDescriptor} descriptor + */ + updateOutputWithDescriptor(output_index, descriptor) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(descriptor, WrapDescriptor); + wasm.wrappsbt_updateOutputWithDescriptor(retptr, this.__wbg_ptr, output_index, descriptor.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + if (r1) { + throw takeObject(r0); + } + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Validate a signature at a specific input against a pubkey + * Returns true if the signature is valid + * + * This method handles both ECDSA (legacy/SegWit) and Schnorr (Taproot) signatures. + * The pubkey should be provided as bytes (33 bytes for compressed ECDSA, 32 bytes for x-only Schnorr). + * @param {number} input_index + * @param {Uint8Array} pubkey + * @returns {boolean} + */ + validateSignatureAtInput(input_index, pubkey) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(pubkey, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + wasm.wrappsbt_validateSignatureAtInput(retptr, this.__wbg_ptr, input_index, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Verify a signature at a specific input using a WasmBIP32 key + * + * This method verifies if a valid signature exists for the given BIP32 key at the specified input. + * It handles both ECDSA (legacy/SegWit) and Schnorr (Taproot) signatures. + * + * Note: This method checks if the key's public key matches any signature in the input. + * For proper BIP32 verification, the key should be derived to the correct path first. + * + * # Arguments + * * `input_index` - The index of the input to check + * * `key` - The WasmBIP32 key to verify against + * + * # Returns + * `true` if a valid signature exists for the key, `false` otherwise + * @param {number} input_index + * @param {WasmBIP32} key + * @returns {boolean} + */ + verifySignatureWithKey(input_index, key) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + _assertClass(key, WasmBIP32); + wasm.wrappsbt_verifySignatureWithKey(retptr, this.__wbg_ptr, input_index, key.__wbg_ptr); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + if (r2) { + throw takeObject(r1); + } + return r0 !== 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } + } + /** + * Get the transaction version + * @returns {number} + */ + version() { + const ret = wasm.wrappsbt_version(this.__wbg_ptr); + return ret; + } +} +if (Symbol.dispose) WrapPsbt.prototype[Symbol.dispose] = WrapPsbt.prototype.free; + +/** + * Check if the inspect feature is enabled. + * + * # Returns + * `true` if the feature is enabled, `false` otherwise + * @returns {boolean} + */ +export function isInspectEnabled() { + const ret = wasm.isInspectEnabled(); + return ret !== 0; +} + +/** + * Parse a PSBT at the raw byte level and return a JSON representation. + * + * Unlike `parsePsbtToJson`, this function exposes the raw key-value pair + * structure as defined in BIP-174, showing: + * - Raw key type IDs and their human-readable names + * - Proprietary keys with their structured format + * - Unknown/unrecognized keys that standard parsers might skip + * + * # Arguments + * * `psbt_bytes` - The raw PSBT bytes + * * `coin_name` - The network coin name (e.g., "btc", "ltc", "zec") + * + * # Returns + * A JSON string representing the raw PSBT key-value structure + * + * # Errors + * Returns an error if: + * - The `inspect` feature is not enabled + * - The PSBT bytes are invalid + * - The network name is unknown + * @param {Uint8Array} psbt_bytes + * @param {string} coin_name + * @returns {string} + */ +export function parsePsbtRawToJson(psbt_bytes, coin_name) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(psbt_bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(coin_name, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.parsePsbtRawToJson(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1); + } +} + +/** + * Parse a PSBT and return a JSON representation of its structure. + * + * This function parses the PSBT using the standard bitcoin crate parser + * and returns a hierarchical node structure suitable for display. + * + * # Arguments + * * `psbt_bytes` - The raw PSBT bytes + * * `coin_name` - The network coin name (e.g., "btc", "ltc", "bch") + * + * # Returns + * A JSON string representing the parsed PSBT structure + * + * # Errors + * Returns an error if: + * - The `inspect` feature is not enabled + * - The PSBT bytes are invalid + * - The network name is unknown + * @param {Uint8Array} psbt_bytes + * @param {string} coin_name + * @returns {string} + */ +export function parsePsbtToJson(psbt_bytes, coin_name) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(psbt_bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(coin_name, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.parsePsbtToJson(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1); + } +} + +/** + * Parse a transaction and return a JSON representation of its structure. + * + * # Arguments + * * `tx_bytes` - The raw transaction bytes + * * `coin_name` - The network coin name (e.g., "btc", "ltc", "bch") + * + * # Returns + * A JSON string representing the parsed transaction structure + * + * # Errors + * Returns an error if: + * - The `inspect` feature is not enabled + * - The transaction bytes are invalid + * - The network name is unknown + * @param {Uint8Array} tx_bytes + * @param {string} coin_name + * @returns {string} + */ +export function parseTxToJson(tx_bytes, coin_name) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(tx_bytes, wasm.__wbindgen_export); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(coin_name, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len1 = WASM_VECTOR_LEN; + wasm.parseTxToJson(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export4(deferred4_0, deferred4_1, 1); + } +} +export function __wbg_Error_8c4e43fe74559d73(arg0, arg1) { + const ret = Error(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); +} +export function __wbg___wbindgen_is_function_0095a73b8b156f76(arg0) { + const ret = typeof(getObject(arg0)) === 'function'; + return ret; +} +export function __wbg___wbindgen_is_null_ac34f5003991759a(arg0) { + const ret = getObject(arg0) === null; + return ret; +} +export function __wbg___wbindgen_is_object_5ae8e5880f2c1fbd(arg0) { + const val = getObject(arg0); + const ret = typeof(val) === 'object' && val !== null; + return ret; +} +export function __wbg___wbindgen_is_string_cd444516edc5b180(arg0) { + const ret = typeof(getObject(arg0)) === 'string'; + return ret; +} +export function __wbg___wbindgen_is_undefined_9e4d92534c42d778(arg0) { + const ret = getObject(arg0) === undefined; + return ret; +} +export function __wbg___wbindgen_number_get_8ff4255516ccad3e(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'number' ? obj : undefined; + getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); +} +export function __wbg___wbindgen_string_get_72fb696202c56729(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); +} +export function __wbg___wbindgen_throw_be289d5034ed271b(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); +} +export function __wbg_call_389efe28435a9388() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).call(getObject(arg1)); + return addHeapObject(ret); +}, arguments); } +export function __wbg_call_4708e0c13bdc8e95() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).call(getObject(arg1), getObject(arg2)); + return addHeapObject(ret); +}, arguments); } +export function __wbg_crypto_574e78ad8b13b65f(arg0) { + const ret = getObject(arg0).crypto; + return addHeapObject(ret); +} +export function __wbg_getRandomValues_b8f5dbd5f3995a9e() { return handleError(function (arg0, arg1) { + getObject(arg0).getRandomValues(getObject(arg1)); +}, arguments); } +export function __wbg_get_b3ed3ad4be2bc8ac() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(getObject(arg0), getObject(arg1)); + return addHeapObject(ret); +}, arguments); } +export function __wbg_length_32ed9a279acd054c(arg0) { + const ret = getObject(arg0).length; + return ret; +} +export function __wbg_msCrypto_a61aeb35a24c1329(arg0) { + const ret = getObject(arg0).msCrypto; + return addHeapObject(ret); +} +export function __wbg_new_361308b2356cecd0() { + const ret = new Object(); + return addHeapObject(ret); +} +export function __wbg_new_3eb36ae241fe6f44() { + const ret = new Array(); + return addHeapObject(ret); +} +export function __wbg_new_72b49615380db768(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); +} +export function __wbg_new_dd2b680c8bf6ae29(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); +} +export function __wbg_new_from_slice_a3d2629dc1826784(arg0, arg1) { + const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1)); + return addHeapObject(ret); +} +export function __wbg_new_no_args_1c7c842f08d00ebb(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); +} +export function __wbg_new_with_length_a2c39cbe88fd8ff1(arg0) { + const ret = new Uint8Array(arg0 >>> 0); + return addHeapObject(ret); +} +export function __wbg_node_905d3e251edff8a2(arg0) { + const ret = getObject(arg0).node; + return addHeapObject(ret); +} +export function __wbg_process_dc0fbacc7c1c06f7(arg0) { + const ret = getObject(arg0).process; + return addHeapObject(ret); +} +export function __wbg_prototypesetcall_bdcdcc5842e4d77d(arg0, arg1, arg2) { + Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2)); +} +export function __wbg_push_8ffdcb2063340ba5(arg0, arg1) { + const ret = getObject(arg0).push(getObject(arg1)); + return ret; +} +export function __wbg_randomFillSync_ac0988aba3254290() { return handleError(function (arg0, arg1) { + getObject(arg0).randomFillSync(takeObject(arg1)); +}, arguments); } +export function __wbg_require_60cc747a6bc5215a() { return handleError(function () { + const ret = module.require; + return addHeapObject(ret); +}, arguments); } +export function __wbg_set_6cb8631f80447a67() { return handleError(function (arg0, arg1, arg2) { + const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2)); + return ret; +}, arguments); } +export function __wbg_static_accessor_GLOBAL_12837167ad935116() { + const ret = typeof global === 'undefined' ? null : global; + return isLikeNone(ret) ? 0 : addHeapObject(ret); +} +export function __wbg_static_accessor_GLOBAL_THIS_e628e89ab3b1c95f() { + const ret = typeof globalThis === 'undefined' ? null : globalThis; + return isLikeNone(ret) ? 0 : addHeapObject(ret); +} +export function __wbg_static_accessor_SELF_a621d3dfbb60d0ce() { + const ret = typeof self === 'undefined' ? null : self; + return isLikeNone(ret) ? 0 : addHeapObject(ret); +} +export function __wbg_static_accessor_WINDOW_f8727f0cf888e0bd() { + const ret = typeof window === 'undefined' ? null : window; + return isLikeNone(ret) ? 0 : addHeapObject(ret); +} +export function __wbg_subarray_a96e1fef17ed23cb(arg0, arg1, arg2) { + const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); +} +export function __wbg_versions_c01dfd4722a88165(arg0) { + const ret = getObject(arg0).versions; + return addHeapObject(ret); +} +export function __wbg_wasmdashtransaction_new(arg0) { + const ret = WasmDashTransaction.__wrap(arg0); + return addHeapObject(ret); +} +export function __wbg_wasmecpair_unwrap(arg0) { + const ret = WasmECPair.__unwrap(getObject(arg0)); + return ret; +} +export function __wbg_wasmtransaction_new(arg0) { + const ret = WasmTransaction.__wrap(arg0); + return addHeapObject(ret); +} +export function __wbg_wasmzcashtransaction_new(arg0) { + const ret = WasmZcashTransaction.__wrap(arg0); + return addHeapObject(ret); +} +export function __wbindgen_cast_0000000000000001(arg0) { + // Cast intrinsic for `F64 -> Externref`. + const ret = arg0; + return addHeapObject(ret); +} +export function __wbindgen_cast_0000000000000002(arg0, arg1) { + // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`. + const ret = getArrayU8FromWasm0(arg0, arg1); + return addHeapObject(ret); +} +export function __wbindgen_cast_0000000000000003(arg0, arg1) { + // Cast intrinsic for `Ref(String) -> Externref`. + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); +} +export function __wbindgen_cast_0000000000000004(arg0) { + // Cast intrinsic for `U64 -> Externref`. + const ret = BigInt.asUintN(64, arg0); + return addHeapObject(ret); +} +export function __wbindgen_object_clone_ref(arg0) { + const ret = getObject(arg0); + return addHeapObject(ret); +} +export function __wbindgen_object_drop_ref(arg0) { + takeObject(arg0); +} +const AddressNamespaceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_addressnamespace_free(ptr >>> 0, 1)); +const Bip322NamespaceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_bip322namespace_free(ptr >>> 0, 1)); +const BitGoPsbtFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_bitgopsbt_free(ptr >>> 0, 1)); +const FixedScriptWalletNamespaceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_fixedscriptwalletnamespace_free(ptr >>> 0, 1)); +const InscriptionsNamespaceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_inscriptionsnamespace_free(ptr >>> 0, 1)); +const MessageNamespaceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_messagenamespace_free(ptr >>> 0, 1)); +const UtxolibCompatNamespaceFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_utxolibcompatnamespace_free(ptr >>> 0, 1)); +const WasmBIP32Finalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmbip32_free(ptr >>> 0, 1)); +const WasmDashTransactionFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmdashtransaction_free(ptr >>> 0, 1)); +const WasmDimensionsFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmdimensions_free(ptr >>> 0, 1)); +const WasmECPairFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmecpair_free(ptr >>> 0, 1)); +const WasmReplayProtectionFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmreplayprotection_free(ptr >>> 0, 1)); +const WasmRootWalletKeysFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmrootwalletkeys_free(ptr >>> 0, 1)); +const WasmTransactionFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmtransaction_free(ptr >>> 0, 1)); +const WasmZcashTransactionFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wasmzcashtransaction_free(ptr >>> 0, 1)); +const WrapDescriptorFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wrapdescriptor_free(ptr >>> 0, 1)); +const WrapMiniscriptFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wrapminiscript_free(ptr >>> 0, 1)); +const WrapPsbtFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_wrappsbt_free(ptr >>> 0, 1)); + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); + } +} + +function addBorrowedObject(obj) { + if (stack_pointer == 1) throw new Error('out of js stack'); + heap[--stack_pointer] = obj; + return stack_pointer; +} + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function getArrayJsValueFromWasm0(ptr, len) { + ptr = ptr >>> 0; + const mem = getDataViewMemory0(); + const result = []; + for (let i = ptr; i < ptr + 4 * len; i += 4) { + result.push(takeObject(mem.getUint32(i, true))); + } + return result; +} + +function getArrayU32FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len); +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} + +let cachedDataViewMemory0 = null; +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return decodeText(ptr, len); +} + +let cachedUint32ArrayMemory0 = null; +function getUint32ArrayMemory0() { + if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) { + cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer); + } + return cachedUint32ArrayMemory0; +} + +let cachedUint8ArrayMemory0 = null; +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getObject(idx) { return heap[idx]; } + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + wasm.__wbindgen_export3(addHeapObject(e)); + } +} + +let heap = new Array(128).fill(undefined); +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8ArrayMemory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0; + const mem = getDataViewMemory0(); + for (let i = 0; i < array.length; i++) { + mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true); + } + WASM_VECTOR_LEN = array.length; + return ptr; +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let stack_pointer = 128; + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const cachedTextEncoder = new TextEncoder(); + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; + }; +} + +let WASM_VECTOR_LEN = 0; + + +let wasm; +export function __wbg_set_wasm(val) { + wasm = val; +} diff --git a/packages/webui/wasm/wasm_utxo_bg.wasm.d.ts b/packages/webui/wasm/wasm_utxo_bg.wasm.d.ts new file mode 100644 index 00000000..599ed30e --- /dev/null +++ b/packages/webui/wasm/wasm_utxo_bg.wasm.d.ts @@ -0,0 +1,218 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export const __wbg_inscriptionsnamespace_free: (a: number, b: number) => void; +export const __wbg_utxolibcompatnamespace_free: (a: number, b: number) => void; +export const __wbg_wasmtransaction_free: (a: number, b: number) => void; +export const __wbg_wasmzcashtransaction_free: (a: number, b: number) => void; +export const inscriptionsnamespace_create_inscription_reveal_data: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void; +export const inscriptionsnamespace_sign_reveal_transaction: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: bigint) => void; +export const utxolibcompatnamespace_from_output_script: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const utxolibcompatnamespace_to_output_script: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const wasmtransaction_add_input: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const wasmtransaction_add_output: (a: number, b: number, c: number, d: bigint) => number; +export const wasmtransaction_create: () => number; +export const wasmtransaction_from_bytes: (a: number, b: number, c: number) => void; +export const wasmtransaction_get_txid: (a: number, b: number) => void; +export const wasmtransaction_get_vsize: (a: number) => number; +export const wasmtransaction_to_bytes: (a: number, b: number) => void; +export const wasmzcashtransaction_from_bytes: (a: number, b: number, c: number) => void; +export const wasmzcashtransaction_get_txid: (a: number, b: number) => void; +export const wasmzcashtransaction_to_bytes: (a: number, b: number) => void; +export const __wbg_wasmreplayprotection_free: (a: number, b: number) => void; +export const __wbg_wasmrootwalletkeys_free: (a: number, b: number) => void; +export const wasmreplayprotection_from_addresses: (a: number, b: number, c: number, d: number, e: number) => void; +export const wasmreplayprotection_from_output_scripts: (a: number, b: number) => number; +export const wasmreplayprotection_from_public_keys: (a: number, b: number, c: number) => void; +export const wasmrootwalletkeys_backup_key: (a: number) => number; +export const wasmrootwalletkeys_bitgo_key: (a: number) => number; +export const wasmrootwalletkeys_new: (a: number, b: number, c: number, d: number) => void; +export const wasmrootwalletkeys_user_key: (a: number) => number; +export const wasmrootwalletkeys_with_derivation_prefixes: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void; +export const __wbg_addressnamespace_free: (a: number, b: number) => void; +export const __wbg_wasmecpair_free: (a: number, b: number) => void; +export const __wbg_wrappsbt_free: (a: number, b: number) => void; +export const addressnamespace_from_output_script_with_coin: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void; +export const addressnamespace_to_output_script_with_coin: (a: number, b: number, c: number, d: number, e: number) => void; +export const isInspectEnabled: () => number; +export const parsePsbtRawToJson: (a: number, b: number, c: number, d: number, e: number) => void; +export const parsePsbtToJson: (a: number, b: number, c: number, d: number, e: number) => void; +export const parseTxToJson: (a: number, b: number, c: number, d: number, e: number) => void; +export const wasmecpair_from_private_key: (a: number, b: number, c: number) => void; +export const wasmecpair_from_public_key: (a: number, b: number, c: number) => void; +export const wasmecpair_from_wif: (a: number, b: number, c: number) => void; +export const wasmecpair_from_wif_mainnet: (a: number, b: number, c: number) => void; +export const wasmecpair_from_wif_testnet: (a: number, b: number, c: number) => void; +export const wasmecpair_private_key: (a: number) => number; +export const wasmecpair_public_key: (a: number) => number; +export const wasmecpair_to_wif: (a: number, b: number) => void; +export const wasmecpair_to_wif_mainnet: (a: number, b: number) => void; +export const wasmecpair_to_wif_testnet: (a: number, b: number) => void; +export const wrappsbt_addInput: (a: number, b: number, c: number, d: number, e: number, f: bigint, g: number, h: number, i: number) => void; +export const wrappsbt_addOutput: (a: number, b: number, c: number, d: bigint) => number; +export const wrappsbt_clone: (a: number) => number; +export const wrappsbt_deserialize: (a: number, b: number, c: number) => void; +export const wrappsbt_extractTransaction: (a: number, b: number) => void; +export const wrappsbt_finalize: (a: number, b: number) => void; +export const wrappsbt_getInputs: (a: number, b: number) => void; +export const wrappsbt_getOutputs: (a: number, b: number) => void; +export const wrappsbt_getOutputsWithAddress: (a: number, b: number, c: number, d: number) => void; +export const wrappsbt_getPartialSignatures: (a: number, b: number, c: number) => void; +export const wrappsbt_getUnsignedTx: (a: number, b: number) => void; +export const wrappsbt_hasPartialSignatures: (a: number, b: number, c: number) => void; +export const wrappsbt_inputCount: (a: number) => number; +export const wrappsbt_lockTime: (a: number) => number; +export const wrappsbt_new: (a: number, b: number) => number; +export const wrappsbt_outputCount: (a: number) => number; +export const wrappsbt_removeOutput: (a: number, b: number, c: number) => void; +export const wrappsbt_serialize: (a: number, b: number) => void; +export const wrappsbt_signAll: (a: number, b: number, c: number) => void; +export const wrappsbt_signAllWithEcpair: (a: number, b: number, c: number) => void; +export const wrappsbt_signWithPrv: (a: number, b: number, c: number, d: number) => void; +export const wrappsbt_signWithXprv: (a: number, b: number, c: number, d: number) => void; +export const wrappsbt_unsignedTxId: (a: number, b: number) => void; +export const wrappsbt_updateInputWithDescriptor: (a: number, b: number, c: number, d: number) => void; +export const wrappsbt_updateOutputWithDescriptor: (a: number, b: number, c: number, d: number) => void; +export const wrappsbt_validateSignatureAtInput: (a: number, b: number, c: number, d: number, e: number) => void; +export const wrappsbt_verifySignatureWithKey: (a: number, b: number, c: number, d: number) => void; +export const wrappsbt_version: (a: number) => number; +export const __wbg_wrapdescriptor_free: (a: number, b: number) => void; +export const __wbg_wrapminiscript_free: (a: number, b: number) => void; +export const wrapdescriptor_atDerivationIndex: (a: number, b: number, c: number) => void; +export const wrapdescriptor_descType: (a: number, b: number) => void; +export const wrapdescriptor_encode: (a: number, b: number) => void; +export const wrapdescriptor_fromString: (a: number, b: number, c: number, d: number, e: number) => void; +export const wrapdescriptor_fromStringDetectType: (a: number, b: number, c: number) => void; +export const wrapdescriptor_hasWildcard: (a: number) => number; +export const wrapdescriptor_maxWeightToSatisfy: (a: number, b: number) => void; +export const wrapdescriptor_node: (a: number, b: number) => void; +export const wrapdescriptor_scriptPubkey: (a: number, b: number) => void; +export const wrapdescriptor_toAsmString: (a: number, b: number) => void; +export const wrapdescriptor_toString: (a: number, b: number) => void; +export const wrapminiscript_encode: (a: number, b: number) => void; +export const wrapminiscript_fromBitcoinScript: (a: number, b: number, c: number, d: number, e: number) => void; +export const wrapminiscript_fromString: (a: number, b: number, c: number, d: number, e: number) => void; +export const wrapminiscript_node: (a: number, b: number) => void; +export const wrapminiscript_toAsmString: (a: number, b: number) => void; +export const wrapminiscript_toString: (a: number, b: number) => void; +export const __wbg_bip322namespace_free: (a: number, b: number) => void; +export const __wbg_bitgopsbt_free: (a: number, b: number) => void; +export const __wbg_fixedscriptwalletnamespace_free: (a: number, b: number) => void; +export const __wbg_messagenamespace_free: (a: number, b: number) => void; +export const __wbg_wasmbip32_free: (a: number, b: number) => void; +export const __wbg_wasmdashtransaction_free: (a: number, b: number) => void; +export const __wbg_wasmdimensions_free: (a: number, b: number) => void; +export const bip322namespace_add_bip322_input: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number) => void; +export const bip322namespace_verify_bip322_psbt_input: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => void; +export const bip322namespace_verify_bip322_psbt_input_with_pubkeys: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number) => void; +export const bip322namespace_verify_bip322_tx_input: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number) => void; +export const bip322namespace_verify_bip322_tx_input_with_pubkeys: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number) => void; +export const bitgopsbt_add_input: (a: number, b: number, c: number, d: number, e: number, f: bigint, g: number, h: number, i: number, j: number, k: number) => void; +export const bitgopsbt_add_output: (a: number, b: number, c: number, d: number, e: bigint) => void; +export const bitgopsbt_add_output_with_address: (a: number, b: number, c: number, d: number, e: bigint) => void; +export const bitgopsbt_add_paygo_attestation: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void; +export const bitgopsbt_add_replay_protection_input: (a: number, b: number, c: number, d: number, e: number, f: number, g: bigint, h: number, i: number, j: number) => void; +export const bitgopsbt_add_wallet_input: (a: number, b: number, c: number, d: number, e: number, f: bigint, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number) => void; +export const bitgopsbt_add_wallet_output: (a: number, b: number, c: number, d: number, e: bigint, f: number) => void; +export const bitgopsbt_combine_musig2_nonces: (a: number, b: number, c: number) => void; +export const bitgopsbt_create_empty: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const bitgopsbt_create_empty_zcash: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void; +export const bitgopsbt_create_empty_zcash_at_height: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void; +export const bitgopsbt_expiry_height: (a: number) => number; +export const bitgopsbt_extract_bitcoin_transaction: (a: number, b: number) => void; +export const bitgopsbt_extract_dash_transaction: (a: number, b: number) => void; +export const bitgopsbt_extract_half_signed_legacy_tx: (a: number, b: number) => void; +export const bitgopsbt_extract_transaction: (a: number, b: number) => void; +export const bitgopsbt_extract_zcash_transaction: (a: number, b: number) => void; +export const bitgopsbt_finalize_all_inputs: (a: number, b: number) => void; +export const bitgopsbt_from_bytes: (a: number, b: number, c: number, d: number, e: number) => void; +export const bitgopsbt_generate_musig2_nonces: (a: number, b: number, c: number, d: number, e: number) => void; +export const bitgopsbt_get_inputs: (a: number, b: number) => void; +export const bitgopsbt_get_network_type: (a: number, b: number) => void; +export const bitgopsbt_get_outputs: (a: number, b: number) => void; +export const bitgopsbt_get_outputs_with_address: (a: number, b: number) => void; +export const bitgopsbt_input_count: (a: number) => number; +export const bitgopsbt_is_musig2_input: (a: number, b: number) => number; +export const bitgopsbt_lock_time: (a: number) => number; +export const bitgopsbt_network: (a: number, b: number) => void; +export const bitgopsbt_output_count: (a: number) => number; +export const bitgopsbt_parse_outputs_with_wallet_keys: (a: number, b: number, c: number, d: number, e: number) => void; +export const bitgopsbt_parse_transaction_with_wallet_keys: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const bitgopsbt_serialize: (a: number, b: number) => void; +export const bitgopsbt_sign_all_musig2_inputs: (a: number, b: number, c: number) => void; +export const bitgopsbt_sign_all_replay_protection_inputs: (a: number, b: number, c: number) => void; +export const bitgopsbt_sign_all_wallet_inputs: (a: number, b: number, c: number) => void; +export const bitgopsbt_sign_musig2_input: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_sign_single_input_with_privkey: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_sign_single_input_with_xpriv: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_sign_with_privkey: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_sign_with_xpriv: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_unsigned_txid: (a: number, b: number) => void; +export const bitgopsbt_verify_replay_protection_signature: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_verify_signature_with_pub: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_verify_signature_with_xpub: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_version: (a: number) => number; +export const bitgopsbt_version_group_id: (a: number) => number; +export const fixedscriptwalletnamespace_address: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void; +export const fixedscriptwalletnamespace_address_with_network_str: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void; +export const fixedscriptwalletnamespace_chain_code_table: () => number; +export const fixedscriptwalletnamespace_create_op_return_script: (a: number, b: number, c: number) => void; +export const fixedscriptwalletnamespace_output_script: (a: number, b: number, c: number, d: number, e: number) => void; +export const fixedscriptwalletnamespace_output_script_with_network_str: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const fixedscriptwalletnamespace_p2sh_p2pk_output_script: (a: number, b: number, c: number) => void; +export const fixedscriptwalletnamespace_supports_script_type: (a: number, b: number, c: number, d: number, e: number) => void; +export const messagenamespace_sign_message: (a: number, b: number, c: number, d: number) => void; +export const messagenamespace_verify_message: (a: number, b: number, c: number, d: number, e: number, f: number) => void; +export const wasmbip32_chain_code: (a: number) => number; +export const wasmbip32_depth: (a: number) => number; +export const wasmbip32_derive: (a: number, b: number, c: number) => void; +export const wasmbip32_derive_hardened: (a: number, b: number, c: number) => void; +export const wasmbip32_derive_path: (a: number, b: number, c: number, d: number) => void; +export const wasmbip32_equals: (a: number, b: number) => number; +export const wasmbip32_fingerprint: (a: number) => number; +export const wasmbip32_from_base58: (a: number, b: number, c: number) => void; +export const wasmbip32_from_bip32_interface: (a: number, b: number) => void; +export const wasmbip32_from_seed: (a: number, b: number, c: number, d: number, e: number) => void; +export const wasmbip32_from_seed_sha256: (a: number, b: number, c: number, d: number, e: number) => void; +export const wasmbip32_from_xprv: (a: number, b: number, c: number) => void; +export const wasmbip32_from_xpub: (a: number, b: number, c: number) => void; +export const wasmbip32_identifier: (a: number) => number; +export const wasmbip32_index: (a: number) => number; +export const wasmbip32_is_neutered: (a: number) => number; +export const wasmbip32_neutered: (a: number) => number; +export const wasmbip32_parent_fingerprint: (a: number) => number; +export const wasmbip32_private_key: (a: number) => number; +export const wasmbip32_public_key: (a: number) => number; +export const wasmbip32_to_base58: (a: number, b: number) => void; +export const wasmbip32_to_wif: (a: number, b: number) => void; +export const wasmdashtransaction_from_bytes: (a: number, b: number, c: number) => void; +export const wasmdashtransaction_get_txid: (a: number, b: number) => void; +export const wasmdashtransaction_to_bytes: (a: number, b: number) => void; +export const wasmdimensions_empty: () => number; +export const wasmdimensions_from_input: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void; +export const wasmdimensions_from_input_script_type: (a: number, b: number, c: number, d: number) => void; +export const wasmdimensions_from_output_script_length: (a: number) => number; +export const wasmdimensions_from_output_script_type: (a: number, b: number, c: number) => void; +export const wasmdimensions_from_psbt: (a: number, b: number) => void; +export const wasmdimensions_get_input_vsize: (a: number, b: number, c: number) => number; +export const wasmdimensions_get_input_weight: (a: number, b: number, c: number) => number; +export const wasmdimensions_get_output_vsize: (a: number) => number; +export const wasmdimensions_get_output_weight: (a: number) => number; +export const wasmdimensions_get_vsize: (a: number, b: number, c: number) => number; +export const wasmdimensions_get_weight: (a: number, b: number, c: number) => number; +export const wasmdimensions_has_segwit: (a: number) => number; +export const wasmdimensions_plus: (a: number, b: number) => number; +export const wasmdimensions_times: (a: number, b: number) => number; +export const wasmbip32_from_bip32_properties: (a: number, b: number) => void; +export const bitgopsbt_sign_wallet_input: (a: number, b: number, c: number, d: number) => void; +export const bitgopsbt_sign_all_with_xpriv: (a: number, b: number, c: number) => void; +export const bitgopsbt_sign_replay_protection_inputs: (a: number, b: number, c: number) => void; +export const rustsecp256k1_v0_10_0_context_create: (a: number) => number; +export const rustsecp256k1_v0_10_0_context_destroy: (a: number) => void; +export const rustsecp256k1_v0_10_0_default_error_callback_fn: (a: number, b: number) => void; +export const rustsecp256k1_v0_10_0_default_illegal_callback_fn: (a: number, b: number) => void; +export const __wbindgen_export: (a: number, b: number) => number; +export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number; +export const __wbindgen_export3: (a: number) => void; +export const __wbindgen_add_to_stack_pointer: (a: number) => number; +export const __wbindgen_export4: (a: number, b: number, c: number) => void;