diff --git a/src/transaction_builder.js b/src/transaction_builder.js
index 9abf242..e63bdd0 100644
--- a/src/transaction_builder.js
+++ b/src/transaction_builder.js
@@ -13,6 +13,33 @@ const transaction_1 = require('./transaction');
 const types = require('./types');
 const typeforce = require('typeforce');
 const SCRIPT_TYPES = classify.types;
+const PREVOUT_TYPES = new Set([
+  // Raw
+  'p2pkh',
+  'p2pk',
+  'p2wpkh',
+  'p2ms',
+  // P2SH wrapped
+  'p2sh-p2pkh',
+  'p2sh-p2pk',
+  'p2sh-p2wpkh',
+  'p2sh-p2ms',
+  // P2WSH wrapped
+  'p2wsh-p2pkh',
+  'p2wsh-p2pk',
+  'p2wsh-p2ms',
+  // P2SH-P2WSH wrapper
+  'p2sh-p2wsh-p2pkh',
+  'p2sh-p2wsh-p2pk',
+  'p2sh-p2wsh-p2ms',
+]);
+function tfMessage(type, value, message) {
+  try {
+    typeforce(type, value);
+  } catch (err) {
+    throw new Error(message);
+  }
+}
 function txIsString(tx) {
   return typeof tx === 'string' || tx instanceof String;
 }
@@ -118,74 +145,29 @@ class TransactionBuilder {
   buildIncomplete() {
     return this.__build(true);
   }
-  sign(vin, keyPair, redeemScript, hashType, witnessValue, witnessScript) {
-    // TODO: remove keyPair.network matching in 4.0.0
-    if (keyPair.network && keyPair.network !== this.network)
-      throw new TypeError('Inconsistent network');
-    if (!this.__INPUTS[vin]) throw new Error('No input at index: ' + vin);
-    hashType = hashType || transaction_1.Transaction.SIGHASH_ALL;
-    if (this.__needsOutputs(hashType))
-      throw new Error('Transaction needs outputs');
-    const input = this.__INPUTS[vin];
-    // if redeemScript was previously provided, enforce consistency
-    if (
-      input.redeemScript !== undefined &&
-      redeemScript &&
-      !input.redeemScript.equals(redeemScript)
-    ) {
-      throw new Error('Inconsistent redeemScript');
-    }
-    const ourPubKey = keyPair.publicKey || keyPair.getPublicKey();
-    if (!canSign(input)) {
-      if (witnessValue !== undefined) {
-        if (input.value !== undefined && input.value !== witnessValue)
-          throw new Error('Input did not match witnessValue');
-        typeforce(types.Satoshi, witnessValue);
-        input.value = witnessValue;
-      }
-      if (!canSign(input)) {
-        const prepared = prepareInput(
-          input,
-          ourPubKey,
-          redeemScript,
-          witnessScript,
-        );
-        // updates inline
-        Object.assign(input, prepared);
-      }
-      if (!canSign(input)) throw Error(input.prevOutType + ' not supported');
-    }
-    // ready to sign
-    let signatureHash;
-    if (input.hasWitness) {
-      signatureHash = this.__TX.hashForWitnessV0(
-        vin,
-        input.signScript,
-        input.value,
+  sign(
+    signParams,
+    keyPair,
+    redeemScript,
+    hashType,
+    witnessValue,
+    witnessScript,
+  ) {
+    trySign(
+      getSigningData(
+        this.network,
+        this.__INPUTS,
+        this.__needsOutputs.bind(this),
+        this.__TX,
+        signParams,
+        keyPair,
+        redeemScript,
         hashType,
-      );
-    } else {
-      signatureHash = this.__TX.hashForSignature(
-        vin,
-        input.signScript,
-        hashType,
-      );
-    }
-    // enforce in order signing of public keys
-    const signed = input.pubkeys.some((pubKey, i) => {
-      if (!ourPubKey.equals(pubKey)) return false;
-      if (input.signatures[i]) throw new Error('Signature already exists');
-      // TODO: add tests
-      if (ourPubKey.length !== 33 && input.hasWitness) {
-        throw new Error(
-          'BIP143 rejects uncompressed public keys in P2WPKH or P2WSH',
-        );
-      }
-      const signature = keyPair.sign(signatureHash, this.__USE_LOW_R);
-      input.signatures[i] = bscript.signature.encode(signature, hashType);
-      return true;
-    });
-    if (!signed) throw new Error('Key pair cannot sign for this input');
+        witnessValue,
+        witnessScript,
+        this.__USE_LOW_R,
+      ),
+    );
   }
   __addInputUnsafe(txHash, vout, options) {
     if (transaction_1.Transaction.isCoinbaseHash(txHash)) {
@@ -746,3 +728,331 @@ function canSign(input) {
 function signatureHashType(buffer) {
   return buffer.readUInt8(buffer.length - 1);
 }
+function checkSignArgs(inputs, signParams) {
+  if (!PREVOUT_TYPES.has(signParams.prevOutScriptType)) {
+    throw new TypeError(
+      `Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
+    );
+  }
+  tfMessage(
+    typeforce.Number,
+    signParams.vin,
+    `sign must include vin parameter as Number (input index)`,
+  );
+  tfMessage(
+    types.Signer,
+    signParams.keyPair,
+    `sign must include keyPair parameter as Signer interface`,
+  );
+  tfMessage(
+    typeforce.maybe(typeforce.Number),
+    signParams.hashType,
+    `sign hashType parameter must be a number`,
+  );
+  const prevOutType = (inputs[signParams.vin] || []).prevOutType;
+  const posType = signParams.prevOutScriptType;
+  switch (posType) {
+    case 'p2pkh':
+      if (prevOutType && prevOutType !== 'pubkeyhash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2pkh: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2pk':
+      if (prevOutType && prevOutType !== 'pubkey') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2pk: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2wpkh':
+      if (prevOutType && prevOutType !== 'witnesspubkeyhash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2wpkh: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessValue`,
+      );
+      break;
+    case 'p2ms':
+      if (prevOutType && prevOutType !== 'multisig') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2ms: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2sh-p2wpkh':
+      if (prevOutType && prevOutType !== 'scripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2sh-p2wpkh: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.Buffer,
+        signParams.redeemScript,
+        `${posType} requires redeemScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessValue`,
+      );
+      break;
+    case 'p2sh-p2ms':
+    case 'p2sh-p2pk':
+    case 'p2sh-p2pkh':
+      if (prevOutType && prevOutType !== 'scripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type ${posType}: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.Buffer,
+        signParams.redeemScript,
+        `${posType} requires redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2wsh-p2ms':
+    case 'p2wsh-p2pk':
+    case 'p2wsh-p2pkh':
+      if (prevOutType && prevOutType !== 'witnessscripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type ${posType}: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.Buffer,
+        signParams.witnessScript,
+        `${posType} requires witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessValue`,
+      );
+      break;
+    case 'p2sh-p2wsh-p2ms':
+    case 'p2sh-p2wsh-p2pk':
+    case 'p2sh-p2wsh-p2pkh':
+      if (prevOutType && prevOutType !== 'scripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type ${posType}: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.Buffer,
+        signParams.witnessScript,
+        `${posType} requires witnessScript`,
+      );
+      tfMessage(
+        typeforce.Buffer,
+        signParams.redeemScript,
+        `${posType} requires witnessScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessScript`,
+      );
+      break;
+  }
+}
+function trySign({
+  input,
+  ourPubKey,
+  keyPair,
+  signatureHash,
+  hashType,
+  useLowR,
+}) {
+  // enforce in order signing of public keys
+  let signed = false;
+  for (const [i, pubKey] of input.pubkeys.entries()) {
+    if (!ourPubKey.equals(pubKey)) continue;
+    if (input.signatures[i]) throw new Error('Signature already exists');
+    // TODO: add tests
+    if (ourPubKey.length !== 33 && input.hasWitness) {
+      throw new Error(
+        'BIP143 rejects uncompressed public keys in P2WPKH or P2WSH',
+      );
+    }
+    const signature = keyPair.sign(signatureHash, useLowR);
+    input.signatures[i] = bscript.signature.encode(signature, hashType);
+    signed = true;
+  }
+  if (!signed) throw new Error('Key pair cannot sign for this input');
+}
+function getSigningData(
+  network,
+  inputs,
+  needsOutputs,
+  tx,
+  signParams,
+  keyPair,
+  redeemScript,
+  hashType,
+  witnessValue,
+  witnessScript,
+  useLowR,
+) {
+  let vin;
+  if (typeof signParams === 'number') {
+    console.warn(
+      'DEPRECATED: TransactionBuilder sign method arguments ' +
+        'will change in v6, please use the TxbSignArg interface',
+    );
+    vin = signParams;
+  } else if (typeof signParams === 'object') {
+    checkSignArgs(inputs, signParams);
+    ({
+      vin,
+      keyPair,
+      redeemScript,
+      hashType,
+      witnessValue,
+      witnessScript,
+    } = signParams);
+  } else {
+    throw new TypeError(
+      'TransactionBuilder sign first arg must be TxbSignArg or number',
+    );
+  }
+  if (keyPair === undefined) {
+    throw new Error('sign requires keypair');
+  }
+  // TODO: remove keyPair.network matching in 4.0.0
+  if (keyPair.network && keyPair.network !== network)
+    throw new TypeError('Inconsistent network');
+  if (!inputs[vin]) throw new Error('No input at index: ' + vin);
+  hashType = hashType || transaction_1.Transaction.SIGHASH_ALL;
+  if (needsOutputs(hashType)) throw new Error('Transaction needs outputs');
+  const input = inputs[vin];
+  // if redeemScript was previously provided, enforce consistency
+  if (
+    input.redeemScript !== undefined &&
+    redeemScript &&
+    !input.redeemScript.equals(redeemScript)
+  ) {
+    throw new Error('Inconsistent redeemScript');
+  }
+  const ourPubKey =
+    keyPair.publicKey || (keyPair.getPublicKey && keyPair.getPublicKey());
+  if (!canSign(input)) {
+    if (witnessValue !== undefined) {
+      if (input.value !== undefined && input.value !== witnessValue)
+        throw new Error('Input did not match witnessValue');
+      typeforce(types.Satoshi, witnessValue);
+      input.value = witnessValue;
+    }
+    if (!canSign(input)) {
+      const prepared = prepareInput(
+        input,
+        ourPubKey,
+        redeemScript,
+        witnessScript,
+      );
+      // updates inline
+      Object.assign(input, prepared);
+    }
+    if (!canSign(input)) throw Error(input.prevOutType + ' not supported');
+  }
+  // ready to sign
+  let signatureHash;
+  if (input.hasWitness) {
+    signatureHash = tx.hashForWitnessV0(
+      vin,
+      input.signScript,
+      input.value,
+      hashType,
+    );
+  } else {
+    signatureHash = tx.hashForSignature(vin, input.signScript, hashType);
+  }
+  return {
+    input,
+    ourPubKey,
+    keyPair,
+    signatureHash,
+    hashType,
+    useLowR: !!useLowR,
+  };
+}
diff --git a/src/types.js b/src/types.js
index be95266..8bcee2c 100644
--- a/src/types.js
+++ b/src/types.js
@@ -13,6 +13,14 @@ exports.BIP32Path = BIP32Path;
 BIP32Path.toJSON = () => {
   return 'BIP32 derivation path';
 };
+function Signer(obj) {
+  return (
+    (typeforce.Buffer(obj.publicKey) ||
+      typeof obj.getPublicKey === 'function') &&
+    typeof obj.sign === 'function'
+  );
+}
+exports.Signer = Signer;
 const SATOSHI_MAX = 21 * 1e14;
 function Satoshi(value) {
   return typeforce.UInt53(value) && value <= SATOSHI_MAX;
diff --git a/test/fixtures/transaction_builder.json b/test/fixtures/transaction_builder.json
index 24be3ba..07226b0 100644
--- a/test/fixtures/transaction_builder.json
+++ b/test/fixtures/transaction_builder.json
@@ -11,6 +11,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -34,6 +35,7 @@
             "prevTxScript": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 OP_CHECKSIG",
             "signs": [
               {
+                "prevOutScriptType": "p2pk",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -56,6 +58,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "redeemScript": "OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG"
               }
@@ -80,11 +83,14 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG"
               },
               {
-                "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT"
+                "prevOutScriptType": "p2sh-p2ms",
+                "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
+                "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG"
               }
             ]
           }
@@ -108,9 +114,11 @@
             "prevTxScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx"
               },
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT"
               }
             ]
@@ -135,9 +143,11 @@
             "prevTxScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx"
               },
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT"
               }
             ]
@@ -162,9 +172,11 @@
             "prevTxScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT"
               },
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx"
               }
             ]
@@ -188,11 +200,14 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG"
               },
               {
-                "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe"
+                "prevOutScriptType": "p2sh-p2ms",
+                "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe",
+                "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG"
               }
             ]
           }
@@ -215,12 +230,15 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
                 "hashType": 1
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe",
+                "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
                 "hashType": 2
               }
             ]
@@ -244,6 +262,7 @@
             "prevTxScript": "OP_HASH160 e89677d91455e541630d62c63718bef738b478b1 OP_EQUAL",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pk",
                 "keyPair": "KxLDMPtVM7sLSu2v5n1LybDibw6P9FFbL4pUwJ51UDm7rp5AmXWW",
                 "redeemScript": "033e29aea1168a835d5e386c292082db7b7807172a10ec634ad34226f36d79e70f OP_CHECKSIG"
               }
@@ -267,6 +286,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -291,6 +311,7 @@
             "sequence": 2147001,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -314,6 +335,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -337,6 +359,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "cQ6483mDWwoG8o4tn6nU9Jg52RKMjPUWXSY1vycAyPRXQJ1Pn2Rq"
               }
             ]
@@ -359,6 +382,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -381,6 +405,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -404,6 +429,7 @@
             "prevTxScript": "OP_0 751e76e8199196d454941c45d1b3a323f1433bd6",
             "signs": [
               {
+                "prevOutScriptType": "p2wpkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "value": 10000
               }
@@ -428,6 +454,7 @@
             "prevTxScript": "OP_0 0f9ea7bae7166c980169059e39443ed13324495b0d6678ce716262e879591210",
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2pk",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "witnessScript": "038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_CHECKSIG",
                 "value": 80000
@@ -452,9 +479,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 3,
-                "value": 30000000
+                "hashType": 3
               }
             ],
             "sequence": 4294967295,
@@ -482,9 +509,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 1,
-                "value": 40000
+                "hashType": 1
               }
             ],
             "sequence": 4294967295,
@@ -495,9 +522,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 1,
-                "value": 40000
+                "hashType": 1
               }
             ],
             "sequence": 4294967295,
@@ -508,9 +535,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 1,
-                "value": 40000
+                "hashType": 1
               }
             ],
             "sequence": 4294967295,
@@ -542,9 +569,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 129,
-                "value": 40000
+                "hashType": 129
               }
             ],
             "sequence": 4294967295,
@@ -555,9 +582,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 129,
-                "value": 40000
+                "hashType": 129
               }
             ],
             "sequence": 4294967295,
@@ -568,9 +595,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 129,
-                "value": 40000
+                "hashType": 129
               }
             ],
             "sequence": 4294967295,
@@ -602,9 +629,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 3,
-                "value": 40000
+                "hashType": 3
               }
             ],
             "sequence": 4294967295,
@@ -615,9 +642,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 3,
-                "value": 40000
+                "hashType": 3
               }
             ],
             "sequence": 4294967295,
@@ -628,9 +655,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 3,
-                "value": 40000
+                "hashType": 3
               }
             ],
             "sequence": 4294967295,
@@ -662,9 +689,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 131,
-                "value": 40000
+                "hashType": 131
               }
             ],
             "sequence": 4294967295,
@@ -675,9 +702,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 131,
-                "value": 40000
+                "hashType": 131
               }
             ],
             "sequence": 4294967295,
@@ -688,9 +715,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 131,
-                "value": 40000
+                "hashType": 131
               }
             ],
             "sequence": 4294967295,
@@ -722,9 +749,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 2,
-                "value": 40000
+                "hashType": 2
               }
             ],
             "sequence": 4294967295,
@@ -735,9 +762,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 2,
-                "value": 40000
+                "hashType": 2
               }
             ],
             "sequence": 4294967295,
@@ -748,9 +775,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 2,
-                "value": 40000
+                "hashType": 2
               }
             ],
             "sequence": 4294967295,
@@ -782,9 +809,9 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 130,
-                "value": 40000
+                "hashType": 130
               }
             ],
             "sequence": 4294967295,
@@ -795,9 +822,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 130,
-                "value": 40000
+                "hashType": 130
               }
             ],
             "sequence": 4294967295,
@@ -808,9 +835,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzRGFiqhXB7SyX6idHQkt77B8mX7adnujdg3VG47jdVK2x4wbUYg",
-                "hashType": 130,
-                "value": 40000
+                "hashType": 130
               }
             ],
             "sequence": 4294967295,
@@ -842,9 +869,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pk",
                 "keyPair": "L3Wh2WPg21MWqzMFYsVC7PeBXcq1ow32KRccRihnTUnAhJaZUvg1",
-                "hashType": 1,
-                "value": 625000000
+                "hashType": 1
               }
             ],
             "sequence": 4294967278,
@@ -855,6 +882,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2wpkh",
                 "keyPair": "KzVTBhbMaKrAYagJ11VdTaBrb6yzLykLGyuMBkf9sCFPDxdT8shL",
                 "hashType": 1,
                 "value": 600000000
@@ -886,6 +914,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wpkh",
                 "keyPair": "L57KYn5isHFThD4cohjJgLTZA2vaxnMMKWngnzbttF159yH9dARf",
                 "hashType": 1,
                 "redeemScript": "OP_0 79091972186c449eb1ded22b78e40d009bdf0089",
@@ -909,7 +938,7 @@
         "locktime": 1170
       },
       {
-        "description": "Sighash V1: P2WSH(P2SH(P2MS 6/6))",
+        "description": "Sighash V1: P2SH(P2WSH(P2MS 6/6))",
         "txHex": "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff02e6312761010000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688ac583e0f00000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac0800483045022100f902f491c4df15199e584790ae8c7202569a977accac0a09fa3f4f3b6ec3517602205961a951c4a12fa966da67b6fd75975b9de156b9895f8ab5f289ecaee12b9b3501473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502483045022100bd5294e145d729e9593f49079b74e6e4b8aeba63440408595ce0949d5c6450a702207f9c9fb45907fe0180d3f4bee499006007bb90894b5f824a26dfa5d3afec543303483045022100febf9409d7f3c091ddc4d296a483aae7b3d2a91d38f6ea2a153f7ff085fe7766022078d11972c74cd78f816152463a5e1a5d986dfb94b55cf5f7242e4f6d5df000ff81483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a088247304402201a0e125aed6a700e45d6c86017d5a9d2264c8079319d868f3f163f5d63cb5bfe02200887608f2322ca0d82df67316275371028b0b21750417d594117963fe23b67ec83cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000",
         "version": 1,
         "inputs": [
@@ -918,6 +947,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "L15NqbRvcqso8ZCqD8aFaZV3CTypw6svjk8oCWsAfMmNViahS2Mw",
                 "hashType": 1,
                 "witnessScript": "OP_6 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b OP_6 OP_CHECKMULTISIG",
@@ -925,6 +955,7 @@
                 "value": 987654321
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "Kwpf3fycToLH1ymZUkezFrYwTjhKaucHD861Ft5A4Tih855LBxVx",
                 "hashType": 2,
                 "witnessScript": "OP_6 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b OP_6 OP_CHECKMULTISIG",
@@ -932,6 +963,7 @@
                 "value": 987654321
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "L1EV111k2WzNTapY2etd1TaB2aWbjUgouko9YyipS2S8H8WdGkQi",
                 "hashType": 3,
                 "witnessScript": "OP_6 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b OP_6 OP_CHECKMULTISIG",
@@ -939,6 +971,7 @@
                 "value": 987654321
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "KwuvEmpBtJaw8SQLnpi3CoEHZJvv33EnYBHn13VcDuwprJqmkfSH",
                 "hashType": 129,
                 "witnessScript": "OP_6 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b OP_6 OP_CHECKMULTISIG",
@@ -946,6 +979,7 @@
                 "value": 987654321
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "L5kdM8eWyfj8pdRDWA8j5SmBwAQt2yyhqjb2ZZQxtRGJfCquC6TB",
                 "hashType": 130,
                 "witnessScript": "OP_6 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b OP_6 OP_CHECKMULTISIG",
@@ -953,6 +987,7 @@
                 "value": 987654321
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "KyT4JbJVRy5FZ6ZEZhkaocP2JSBXiF7X3Cx6DBAGLrydR9fiXQUK",
                 "hashType": 131,
                 "witnessScript": "OP_6 0307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba3 03b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b 034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a 033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f4 03a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac16 02d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b OP_6 OP_CHECKMULTISIG",
@@ -986,9 +1021,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pk",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
-                "hashType": 1,
-                "value": 80000
+                "hashType": 1
               }
             ],
             "sequence": 4294967295,
@@ -1013,10 +1048,10 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pk",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
-                "redeemScript": "038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_CHECKSIG",
-                "value": 80000
+                "redeemScript": "038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_CHECKSIG"
               }
             ],
             "sequence": 4294967295,
@@ -1041,6 +1076,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2pk",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "witnessScript": "038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_CHECKSIG",
@@ -1069,6 +1105,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2pk",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "redeemScript": "OP_0 0f9ea7bae7166c980169059e39443ed13324495b0d6678ce716262e879591210",
@@ -1098,9 +1135,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
-                "hashType": 1,
-                "value": 80000
+                "hashType": 1
               }
             ],
             "sequence": 4294967295,
@@ -1125,10 +1162,10 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pkh",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
-                "redeemScript": "OP_DUP OP_HASH160 851a33a5ef0d4279bd5854949174e2c65b1d4500 OP_EQUALVERIFY OP_CHECKSIG",
-                "value": 80000
+                "redeemScript": "OP_DUP OP_HASH160 851a33a5ef0d4279bd5854949174e2c65b1d4500 OP_EQUALVERIFY OP_CHECKSIG"
               }
             ],
             "sequence": 4294967295,
@@ -1153,6 +1190,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2pkh",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "witnessScript": "OP_DUP OP_HASH160 851a33a5ef0d4279bd5854949174e2c65b1d4500 OP_EQUALVERIFY OP_CHECKSIG",
@@ -1181,6 +1219,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2pkh",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "witnessScript": "OP_DUP OP_HASH160 851a33a5ef0d4279bd5854949174e2c65b1d4500 OP_EQUALVERIFY OP_CHECKSIG",
@@ -1210,9 +1249,9 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2ms",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
-                "hashType": 1,
-                "value": 80000
+                "hashType": 1
               }
             ],
             "sequence": 4294967295,
@@ -1237,10 +1276,10 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
-                "redeemScript": "OP_1 038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_1 OP_CHECKMULTISIG",
-                "value": 80000
+                "redeemScript": "OP_1 038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_1 OP_CHECKMULTISIG"
               }
             ],
             "sequence": 4294967295,
@@ -1265,6 +1304,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2ms",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "witnessScript": "OP_1 038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_1 OP_CHECKMULTISIG",
@@ -1293,6 +1333,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "witnessScript": "OP_1 038de63cf582d058a399a176825c045672d5ff8ea25b64d28d4375dcdb14c02b2b OP_1 OP_CHECKMULTISIG",
@@ -1322,6 +1363,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2wpkh",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "value": 80000
@@ -1349,6 +1391,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wpkh",
                 "keyPair": "L2FroWqrUgsPpTMhpXcAFnVDLPTToDbveh3bhDaU4jhe7Cw6YujN",
                 "hashType": 1,
                 "redeemScript": "OP_0 851a33a5ef0d4279bd5854949174e2c65b1d4500",
@@ -1377,6 +1420,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -1402,6 +1446,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS",
                 "witnessScript": "OP_2 02bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e2 02d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea19 OP_2 OP_CHECKMULTISIG",
                 "redeemScript": "OP_0 24376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af",
@@ -1430,12 +1475,14 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS",
                 "witnessScript": "OP_2 02bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e2 02d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea19 OP_2 OP_CHECKMULTISIG",
                 "redeemScript": "OP_0 24376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af",
                 "value": 100000
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "cTUFsNeVd8TKU4yREN8nMdViNnHyNvCCYVRmRUmkMLgomiMWTiii",
                 "witnessScript": "OP_2 02bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e2 02d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea19 OP_2 OP_CHECKMULTISIG",
                 "redeemScript": "OP_0 24376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af",
@@ -1453,7 +1500,7 @@
         ]
       },
       {
-        "description": "P2WSH(P2MS 2/3) -> P2PKH",
+        "description": "P2SH(P2WSH(P2MS 2/3)) -> P2PKH",
         "network": "testnet",
         "txHex": "01000000000101ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01000000232200201b48bf145648b9492ecd6d76754ea3def4b90e22e4ef7aee9ca291b2de455701ffffffff01f07e0e00000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac0400473044022036c9ecb03cb04c09be1f52766725dcfe9a815973bd2f34ce19a345f2d925a45502207b90737852d2508db104ad17612de473687e67928c045555a1ed8d495c0570d901483045022100aec0e58e4e597b35ca5a727702a0da3d4f2ef4759914da7fc80aecb3c479a6d902201ec27ea8dcca4b73ee81e4b627f52f9e627c3497f61e4beeb98f86e02979640a0169522103c411cf39aca4395c81c35921dc832a0d1585d652ab1b52ccc619ff9fbbc5787721020636d944458a4663b75a912c37dc1cd59b11f9a00106783a65ba230d929b96b02102d1448cbf19528a1a27e5958ba73d930b5b3facdbe5c30c7094951a287fcc914953ae00000000",
         "version": 1,
@@ -1466,6 +1513,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "cUxccFVBdJRq6HnyxiFMd8Z15GLThXaNLcnPBgoXLEv9iX6wuV2b",
                 "witnessScript": "OP_2 03c411cf39aca4395c81c35921dc832a0d1585d652ab1b52ccc619ff9fbbc57877 020636d944458a4663b75a912c37dc1cd59b11f9a00106783a65ba230d929b96b0 02d1448cbf19528a1a27e5958ba73d930b5b3facdbe5c30c7094951a287fcc9149 OP_3 OP_CHECKMULTISIG",
                 "redeemScript": "OP_0 1b48bf145648b9492ecd6d76754ea3def4b90e22e4ef7aee9ca291b2de455701",
@@ -1473,6 +1521,7 @@
                 "stage": true
               },
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2ms",
                 "keyPair": "cVSNe9ZdZRsRvEBL8YRR7YiZmH4cLsf5FthgERWkZezJVrGseaXy",
                 "witnessScript": "OP_2 03c411cf39aca4395c81c35921dc832a0d1585d652ab1b52ccc619ff9fbbc57877 020636d944458a4663b75a912c37dc1cd59b11f9a00106783a65ba230d929b96b0 02d1448cbf19528a1a27e5958ba73d930b5b3facdbe5c30c7094951a287fcc9149 OP_3 OP_CHECKMULTISIG",
                 "redeemScript": "OP_0 1b48bf145648b9492ecd6d76754ea3def4b90e22e4ef7aee9ca291b2de455701",
@@ -1561,6 +1610,7 @@
             "scriptSigAfter": "OP_0 OP_0 OP_0 30440220793d87f2a8afeb856816efa38984418c692c15170e99ca371f547454079c0dd3022074ae95e438fee1f37619fabe0ce1083c3be0d65c3defb5337833d50fdc694b1301 52210258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a9121038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f2103b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d953ae",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "cTkcnMZoFYH1UgumzCFHv2veLMNN1PaJyHHUxFT127zhNGBqqEZ2",
                 "redeemScript": "OP_2 0258db1bb3801f1ecde47602143beaeb9cac93251724b8e589fae5c08c1a399a91 038e803e3d84cfc821cc8bf46233a9c2bb359d529db0bcdd3f1a4f38678dd02d7f 03b83e59d848407d7f62a82c99905f5ca3e8e8f5d6400eb78a0b4b067aea0720d9 OP_3 OP_CHECKMULTISIG"
               }
@@ -1585,11 +1635,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001 OP_0 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 1,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
                 "scriptSig": "OP_0 3045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001 3045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b0657601 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52ae"
@@ -1616,11 +1668,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 1,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
                 "scriptSig": "OP_0 OP_0 3045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b0657601 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001 3045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b0657601 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52ae"
@@ -1647,11 +1701,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001 OP_0 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 1,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
                 "scriptSig": "OP_0 3045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001 3045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b0657601 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52ae"
@@ -1678,11 +1734,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 OP_0 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 1,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100ae06d8269b79b5cfa0297d1d88261b0061e52fc2814948c3aa05fa78ee76894302206e0c79a5c90569d8c72a542ef9a06471cbbcd2c651b312339983dfba4f8ff46301 OP_0 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
@@ -1709,11 +1767,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 OP_0 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 2,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
@@ -1740,11 +1800,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 2,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe",
                 "scriptSig": "OP_0 OP_0 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
@@ -1771,11 +1833,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 OP_0 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 2,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe",
                 "scriptSig": "OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
@@ -1802,11 +1866,13 @@
             "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 2,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe",
                 "scriptSig": "OP_0 OP_0 OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "pubKeyIndex": 0,
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "scriptSigBefore": "OP_0 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae",
@@ -1863,6 +1929,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzBQVXYUGDAvqG7VeU3C7ZMRYiwtsxSVVFcYGzKU9E4aUVDUquZU"
               }
             ]
@@ -1900,6 +1967,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               }
             ]
@@ -1927,6 +1995,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG"
               }
@@ -1980,10 +2049,11 @@
         "network": "testnet",
         "inputs": [
           {
-            "txHex": "0100000001f7e6430096cd2790bac115aaab22c0a50fb0a1794305302e1a399e81d8d354f4020000006a47304402205793a862d193264afc32713e2e14541e1ff9ebb647dd7e7e6a0051d0faa87de302205216653741ecbbed573ea2fc053209dd6980616701c27be5b958a159fc97f45a012103e877e7deb32d19250dcfe534ea82c99ad739800295cd5429a7f69e2896c36fcdfeffffff0340420f00000000001976a9145c7b8d623fba952d2387703d051d8e931a6aa0a188ac8bda2702000000001976a9145a0ef60784137d03e7868d063b05424f2f43799f88ac40420f00000000001976a9145c7b8d623fba952d2387703d051d8e931a6aa0a188ac2fcc0e00",
+            "txHex": "01000000000101f7e6430096cd2790bac115aaab22c0a50fb0a1794305302e1a399e81d8d354f40200000000feffffff0340420f00000000001600145c7b8d623fba952d2387703d051d8e931a6aa0a18bda2702000000001976a9145a0ef60784137d03e7868d063b05424f2f43799f88ac40420f00000000001976a9145c7b8d623fba952d2387703d051d8e931a6aa0a188ac0247304402205793a862d193264afc32713e2e14541e1ff9ebb647dd7e7e6a0051d0faa87de302205216653741ecbbed573ea2fc053209dd6980616701c27be5b958a159fc97f45a012103e877e7deb32d19250dcfe534ea82c99ad739800295cd5429a7f69e2896c36fcd2fcc0e00",
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2wpkh",
                 "keyPair": "cQ6483mDWwoG8o4tn6nU9Jg52RKMjPUWXSY1vycAyPRXQJ1Pn2Rq",
                 "throws": true,
                 "value": 22500000000
@@ -2007,9 +2077,11 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn"
               },
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "throws": true
               }
@@ -2033,6 +2105,7 @@
             "prevTxScript": "OP_0 15a71ffa7b5bb70cddefcf364494071022efe390",
             "signs": [
               {
+                "prevOutScriptType": "p2wpkh",
                 "keyPair": "5JiHJJjdufSiMxbvnyNcKtQNLYH6SvUpQnRv9yZENFDWTQKQkzC",
                 "value": 10000,
                 "throws": true
@@ -2057,6 +2130,7 @@
             "prevTxScript": "OP_0 5339df4de3854c4208376443ed075014ad996aa349ad6b5abf6c4d20f604d348",
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2pk",
                 "keyPair": "5JiHJJjdufSiMxbvnyNcKtQNLYH6SvUpQnRv9yZENFDWTQKQkzC",
                 "witnessScript": "04f56d09b32cefc818735150bf8560eefdaf30d2edb3fe557bf27682aedaed81bf9aaff7eeb496e088058ec548826c12b521dbb566a862d9b67677910c2b421e06 OP_CHECKSIG",
                 "value": 80000,
@@ -2082,6 +2156,7 @@
             "prevTxScript": "OP_HASH160 5afe12b2827e3eac05fe3f17c59406ef262aa177 OP_EQUAL",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2wsh-p2pk",
                 "keyPair": "5JiHJJjdufSiMxbvnyNcKtQNLYH6SvUpQnRv9yZENFDWTQKQkzC",
                 "redeemScript": "OP_0 5339df4de3854c4208376443ed075014ad996aa349ad6b5abf6c4d20f604d348",
                 "witnessScript": "04f56d09b32cefc818735150bf8560eefdaf30d2edb3fe557bf27682aedaed81bf9aaff7eeb496e088058ec548826c12b521dbb566a862d9b67677910c2b421e06 OP_CHECKSIG",
@@ -2106,6 +2181,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pk",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "redeemScript": "OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474",
                 "throws": true
@@ -2121,7 +2197,7 @@
         ]
       },
       {
-        "exception": "PrevOutScript is scripthash, requires redeemScript",
+        "exception": "p2sh-p2pkh requires redeemScript",
         "inputs": [
           {
             "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
@@ -2129,6 +2205,7 @@
             "prevTxScript": "OP_HASH160 7f67f0521934a57d3039f77f9f32cf313f3ac74b OP_EQUAL",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "throws": true
               }
@@ -2143,7 +2220,7 @@
         ]
       },
       {
-        "exception": "PrevOutScript is witnessscripthash, requires witnessScript",
+        "exception": "p2wsh-p2pk requires witnessScript",
         "inputs": [
           {
             "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
@@ -2151,6 +2228,7 @@
             "prevTxScript": "OP_0 0f9ea7bae7166c980169059e39443ed13324495b0d6678ce716262e879591210",
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2pk",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "throws": true
               }
@@ -2173,10 +2251,12 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "redeemScript": "OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "redeemScript": "OP_1 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
                 "throws": true
@@ -2201,9 +2281,9 @@
             "prevTxScript": "OP_HASH160 ffffffffffffffffffffffffffffffffffffffff OP_EQUAL",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pkh",
                 "keyPair": "5JiHJJjdufSiMxbvnyNcKtQNLYH6SvUpQnRv9yZENFDWTQKQkzC",
                 "redeemScript": "OP_1",
-                "value": 10000,
                 "throws": true
               }
             ]
@@ -2226,6 +2306,7 @@
             "prevTxScript": "OP_0 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
             "signs": [
               {
+                "prevOutScriptType": "p2wsh-p2pkh",
                 "keyPair": "5JiHJJjdufSiMxbvnyNcKtQNLYH6SvUpQnRv9yZENFDWTQKQkzC",
                 "witnessScript": "OP_1",
                 "value": 10000,
@@ -2249,6 +2330,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "redeemScript": "OP_HASH160 7f67f0521934a57d3039f77f9f32cf313f3ac74b OP_EQUAL",
                 "throws": true
@@ -2264,7 +2346,7 @@
         ]
       },
       {
-        "exception": "PrevOutScript must be P2SH",
+        "exception": "input #0 is not of type p2sh-p2pkh: pubkeyhash",
         "inputs": [
           {
             "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
@@ -2272,6 +2354,7 @@
             "prevTxScript": "OP_DUP OP_HASH160 aa4d7985c57e011a8b3dd8e0e5a73aaef41629c5 OP_EQUALVERIFY OP_CHECKSIG",
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "redeemScript": "OP_1 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_1 OP_CHECKMULTISIG",
                 "throws": true
@@ -2295,11 +2378,14 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf",
                 "redeemScript": "OP_1 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_1 OP_CHECKMULTISIG"
               },
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf",
+                "redeemScript": "OP_1 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_1 OP_CHECKMULTISIG",
                 "throws": true
               }
             ]
@@ -2322,6 +2408,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
                 "network": "testnet",
                 "throws": true
@@ -2345,6 +2432,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2sh-p2ms",
                 "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
                 "redeemScript": "OP_1 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_1 OP_CHECKMULTISIG",
                 "throws": true
@@ -2360,7 +2448,7 @@
         ]
       },
       {
-        "exception": "nulldata not supported",
+        "exception": "input #0 is not of type p2pkh: nulldata",
         "inputs": [
           {
             "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
@@ -2368,6 +2456,7 @@
             "prevTxScript": "OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474",
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
                 "throws": true
               }
@@ -2381,6 +2470,190 @@
           }
         ]
       },
+      {
+        "exception": "input #0 is not of type p2pk: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2pk",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "input #0 is not of type p2wpkh: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2wpkh",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "input #0 is not of type p2ms: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2ms",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "input #0 is not of type p2sh-p2wpkh: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2sh-p2wpkh",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "input #0 is not of type p2sh-p2pk: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2sh-p2pk",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "input #0 is not of type p2wsh-p2pk: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2wsh-p2pk",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "input #0 is not of type p2sh-p2wsh-p2pk: nulldata",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "p2sh-p2wsh-p2pk",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
+      {
+        "exception": "Unknown prevOutScriptType \"notvalidtype\"",
+        "inputs": [
+          {
+            "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+            "vout": 0,
+            "prevTxScript": "OP_RETURN deadbeef",
+            "signs": [
+              {
+                "prevOutScriptType": "notvalidtype",
+                "keyPair": "KzrA86mCVMGWnLGBQu9yzQa32qbxb5dvSK4XhyjjGAWSBKYX4rHx",
+                "throws": true
+              }
+            ]
+          }
+        ],
+        "outputs": [
+          {
+            "script": "OP_RETURN deadbeef",
+            "value": 1000
+          }
+        ]
+      },
       {
         "description": "Transaction w/ no outputs (but 1 SIGHASH_NONE)",
         "exception": "Transaction needs outputs",
@@ -2390,6 +2663,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "hashType": 2
               }
@@ -2400,6 +2674,7 @@
             "vout": 1,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "throws": true
               }
@@ -2417,6 +2692,7 @@
             "vout": 0,
             "signs": [
               {
+                "prevOutScriptType": "p2pkh",
                 "keyPair": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                 "throws": true
               }
diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index 8be864a..30b868c 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -92,7 +92,11 @@ async function faucetComplex (output, value) {
   const txvb = new bitcoin.TransactionBuilder(NETWORK)
   txvb.addInput(unspent.txId, unspent.vout, null, p2pkh.output)
   txvb.addOutput(output, value)
-  txvb.sign(0, keyPair)
+  txvb.sign({
+    prevOutScriptType: 'p2pkh',
+    vin: 0,
+    keyPair
+  })
   const txv = txvb.build()
 
   await broadcast(txv.toHex())
diff --git a/test/integration/payments.js b/test/integration/payments.js
index 66b0a13..256bd00 100644
--- a/test/integration/payments.js
+++ b/test/integration/payments.js
@@ -15,12 +15,29 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
   txb.addInput(unspent.txId, unspent.vout, null, prevOutput)
   txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
 
+  const posType = depends.prevOutScriptType
+  const needsValue = !!witnessScript || posType.slice(-6) === 'p2wpkh'
+
   if (depends.signatures) {
     keyPairs.forEach(keyPair => {
-      txb.sign(0, keyPair, redeemScript, null, unspent.value, witnessScript)
+      txb.sign({
+        prevOutScriptType: posType,
+        vin: 0,
+        keyPair,
+        redeemScript,
+        witnessValue: needsValue ? unspent.value : undefined,
+        witnessScript,
+      })
     })
   } else if (depends.signature) {
-    txb.sign(0, keyPairs[0], redeemScript, null, unspent.value, witnessScript)
+    txb.sign({
+      prevOutScriptType: posType,
+      vin: 0,
+      keyPair: keyPairs[0],
+      redeemScript,
+      witnessValue: needsValue ? unspent.value : undefined,
+      witnessScript,
+    })
   }
 
   return regtestUtils.broadcast(txb.build().toHex())
@@ -41,12 +58,14 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
 
   describe('bitcoinjs-lib (payments - ' + k + ')', () => {
     it('can broadcast as an output, and be spent as an input', async () => {
-      await buildAndSign(depends, output, null, null)
+      Object.assign(depends, { prevOutScriptType: k })
+      await buildAndSign(depends, output, undefined, undefined)
     })
 
     it('can (as P2SH(' + k + ')) broadcast as an output, and be spent as an input', async () => {
       const p2sh = bitcoin.payments.p2sh({ redeem: { output }, network: NETWORK })
-      await buildAndSign(depends, p2sh.output, p2sh.redeem.output, null)
+      Object.assign(depends, { prevOutScriptType: 'p2sh-' + k })
+      await buildAndSign(depends, p2sh.output, p2sh.redeem.output, undefined)
     })
 
     // NOTE: P2WPKH cannot be wrapped in P2WSH, consensus fail
@@ -54,13 +73,15 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
 
     it('can (as P2WSH(' + k + ')) broadcast as an output, and be spent as an input', async () => {
       const p2wsh = bitcoin.payments.p2wsh({ redeem: { output }, network: NETWORK })
-      await buildAndSign(depends, p2wsh.output, null, p2wsh.redeem.output)
+      Object.assign(depends, { prevOutScriptType: 'p2wsh-' + k })
+      await buildAndSign(depends, p2wsh.output, undefined, p2wsh.redeem.output)
     })
 
     it('can (as P2SH(P2WSH(' + k + '))) broadcast as an output, and be spent as an input', async () => {
       const p2wsh = bitcoin.payments.p2wsh({ redeem: { output }, network: NETWORK })
       const p2sh = bitcoin.payments.p2sh({ redeem: { output: p2wsh.output }, network: NETWORK })
 
+      Object.assign(depends, { prevOutScriptType: 'p2sh-p2wsh-' + k })
       await buildAndSign(depends, p2sh.output, p2sh.redeem.output, p2wsh.redeem.output)
     })
   })
diff --git a/test/integration/transactions.js b/test/integration/transactions.js
index c096b87..464460e 100644
--- a/test/integration/transactions.js
+++ b/test/integration/transactions.js
@@ -18,7 +18,11 @@ describe('bitcoinjs-lib (transactions)', () => {
     txb.addOutput('1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP', 12000)
     // (in)15000 - (out)12000 = (fee)3000, this is the miner fee
 
-    txb.sign(0, alice)
+    txb.sign({
+      prevOutScriptType: 'p2pkh',
+      vin: 0,
+      keyPair: alice
+    })
 
     // prepare for broadcast to the Bitcoin network, see "can broadcast a Transaction" below
     assert.strictEqual(txb.build().toHex(), '01000000019d344070eac3fe6e394a16d06d7704a7d5c0a10eb2a2c16bc98842b7cc20d561000000006b48304502210088828c0bdfcdca68d8ae0caeb6ec62cd3fd5f9b2191848edae33feb533df35d302202e0beadd35e17e7f83a733f5277028a9b453d525553e3f5d2d7a7aa8010a81d60121029f50f51d63b345039a290c94bffd3180c99ed659ff6ea6b1242bca47eb93b59fffffffff01e02e0000000000001976a91406afd46bcdfd22ef94ac122aa11f241244a37ecc88ac00000000')
@@ -36,8 +40,16 @@ describe('bitcoinjs-lib (transactions)', () => {
     txb.addOutput('1JtK9CQw1syfWj1WtFMWomrYdV3W2tWBF9', 170000)
     // (in)(200000 + 300000) - (out)(180000 + 170000) = (fee)150000, this is the miner fee
 
-    txb.sign(1, bob) // Bob signs his input, which was the second input (1th)
-    txb.sign(0, alice) // Alice signs her input, which was the first input (0th)
+    txb.sign({
+      prevOutScriptType: 'p2pkh',
+      vin: 1,
+      keyPair: bob
+    }) // Bob signs his input, which was the second input (1th)
+    txb.sign({
+      prevOutScriptType: 'p2pkh',
+      vin: 0,
+      keyPair: alice
+    }) // Alice signs her input, which was the first input (0th)
 
     // prepare for broadcast to the Bitcoin network, see "can broadcast a Transaction" below
     assert.strictEqual(txb.build().toHex(), '01000000024c94e48a870b85f41228d33cf25213dfcc8dd796e7211ed6b1f9a014809dbbb5060000006a473044022041450c258ce7cac7da97316bf2ea1ce66d88967c4df94f3e91f4c2a30f5d08cb02203674d516e6bb2b0afd084c3551614bd9cec3c2945231245e891b145f2d6951f0012103e05ce435e462ec503143305feb6c00e06a3ad52fbf939e85c65f3a765bb7baacffffffff3077d9de049574c3af9bc9c09a7c9db80f2d94caaf63988c9166249b955e867d000000006b483045022100aeb5f1332c79c446d3f906e4499b2e678500580a3f90329edf1ba502eec9402e022072c8b863f8c8d6c26f4c691ac9a6610aa4200edc697306648ee844cfbc089d7a012103df7940ee7cddd2f97763f67e1fb13488da3fbdd7f9c68ec5ef0864074745a289ffffffff0220bf0200000000001976a9147dd65592d0ab2fe0d0257d571abf032cd9db93dc88ac10980200000000001976a914c42e7ef92fdb603af844d064faad95db9bcdfd3d88ac00000000')
@@ -65,8 +77,16 @@ describe('bitcoinjs-lib (transactions)', () => {
     // (in)(5e4 + 7e4) - (out)(8e4 + 1e4) = (fee)3e4 = 30000, this is the miner fee
 
     // Alice signs each input with the respective private keys
-    txb.sign(0, alice1)
-    txb.sign(1, alice2)
+    txb.sign({
+      prevOutScriptType: 'p2pkh',
+      vin: 0,
+      keyPair: alice1
+    })
+    txb.sign({
+      prevOutScriptType: 'p2pkh',
+      vin: 1,
+      keyPair: alice2
+    })
 
     // build and broadcast our RegTest network
     await regtestUtils.broadcast(txb.build().toHex())
@@ -85,7 +105,11 @@ describe('bitcoinjs-lib (transactions)', () => {
     txb.addInput(unspent.txId, unspent.vout)
     txb.addOutput(embed.output, 1000)
     txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e5)
-    txb.sign(0, keyPair)
+    txb.sign({
+      prevOutScriptType: 'p2pkh',
+      vin: 0,
+      keyPair,
+    })
 
     // build and broadcast to the RegTest network
     await regtestUtils.broadcast(txb.build().toHex())
@@ -108,8 +132,18 @@ describe('bitcoinjs-lib (transactions)', () => {
     txb.addInput(unspent.txId, unspent.vout)
     txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
 
-    txb.sign(0, keyPairs[0], p2sh.redeem.output)
-    txb.sign(0, keyPairs[2], p2sh.redeem.output)
+    txb.sign({
+      prevOutScriptType: 'p2sh-p2ms',
+      vin: 0,
+      keyPair: keyPairs[0],
+      redeemScript: p2sh.redeem.output,
+    })
+    txb.sign({
+      prevOutScriptType: 'p2sh-p2ms',
+      vin: 0,
+      keyPair: keyPairs[2],
+      redeemScript: p2sh.redeem.output,
+    })
     const tx = txb.build()
 
     // build and broadcast to the Bitcoin RegTest network
@@ -133,7 +167,13 @@ describe('bitcoinjs-lib (transactions)', () => {
     const txb = new bitcoin.TransactionBuilder(regtest)
     txb.addInput(unspent.txId, unspent.vout)
     txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
-    txb.sign(0, keyPair, p2sh.redeem.output, null, unspent.value)
+    txb.sign({
+      prevOutScriptType: 'p2sh-p2wpkh',
+      vin: 0,
+      keyPair: keyPair,
+      redeemScript: p2sh.redeem.output,
+      witnessValue: unspent.value,
+    })
 
     const tx = txb.build()
 
@@ -158,7 +198,12 @@ describe('bitcoinjs-lib (transactions)', () => {
     const txb = new bitcoin.TransactionBuilder(regtest)
     txb.addInput(unspent.txId, unspent.vout, null, p2wpkh.output) // NOTE: provide the prevOutScript!
     txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
-    txb.sign(0, keyPair, null, null, unspent.value) // NOTE: no redeem script
+    txb.sign({
+      prevOutScriptType: 'p2wpkh',
+      vin: 0,
+      keyPair: keyPair,
+      witnessValue: unspent.value,
+    }) // NOTE: no redeem script
     const tx = txb.build()
 
     // build and broadcast (the P2WPKH transaction) to the Bitcoin RegTest network
@@ -183,7 +228,13 @@ describe('bitcoinjs-lib (transactions)', () => {
     const txb = new bitcoin.TransactionBuilder(regtest)
     txb.addInput(unspent.txId, unspent.vout, null, p2wsh.output) // NOTE: provide the prevOutScript!
     txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
-    txb.sign(0, keyPair, null, null, 5e4, p2wsh.redeem.output) // NOTE: provide a witnessScript!
+    txb.sign({
+      prevOutScriptType: 'p2wsh-p2pk',
+      vin: 0,
+      keyPair: keyPair,
+      witnessValue: 5e4,
+      witnessScript: p2wsh.redeem.output,
+    }) // NOTE: provide a witnessScript!
     const tx = txb.build()
 
     // build and broadcast (the P2WSH transaction) to the Bitcoin RegTest network
@@ -215,9 +266,30 @@ describe('bitcoinjs-lib (transactions)', () => {
     const txb = new bitcoin.TransactionBuilder(regtest)
     txb.addInput(unspent.txId, unspent.vout, null, p2sh.output)
     txb.addOutput(regtestUtils.RANDOM_ADDRESS, 3e4)
-    txb.sign(0, keyPairs[0], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
-    txb.sign(0, keyPairs[2], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
-    txb.sign(0, keyPairs[3], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
+    txb.sign({
+      prevOutScriptType: 'p2sh-p2wsh-p2ms',
+      vin: 0,
+      keyPair: keyPairs[0],
+      redeemScript: p2sh.redeem.output,
+      witnessValue: unspent.value,
+      witnessScript: p2wsh.redeem.output,
+    })
+    txb.sign({
+      prevOutScriptType: 'p2sh-p2wsh-p2ms',
+      vin: 0,
+      keyPair: keyPairs[2],
+      redeemScript: p2sh.redeem.output,
+      witnessValue: unspent.value,
+      witnessScript: p2wsh.redeem.output,
+    })
+    txb.sign({
+      prevOutScriptType: 'p2sh-p2wsh-p2ms',
+      vin: 0,
+      keyPair: keyPairs[3],
+      redeemScript: p2sh.redeem.output,
+      witnessValue: unspent.value,
+      witnessScript: p2wsh.redeem.output,
+    })
 
     const tx = txb.build()
 
diff --git a/test/transaction_builder.js b/test/transaction_builder.js
index 1af8272..a135cca 100644
--- a/test/transaction_builder.js
+++ b/test/transaction_builder.js
@@ -11,7 +11,7 @@ const NETWORKS = require('../src/networks')
 
 const fixtures = require('./fixtures/transaction_builder')
 
-function constructSign (f, txb) {
+function constructSign (f, txb, useOldSignArgs) {
   const network = NETWORKS[f.network]
   const stages = f.stages && f.stages.concat()
 
@@ -21,21 +21,36 @@ function constructSign (f, txb) {
       const keyPair = ECPair.fromWIF(sign.keyPair, network)
       let redeemScript
       let witnessScript
-      let value
+      let witnessValue
 
       if (sign.redeemScript) {
         redeemScript = bscript.fromASM(sign.redeemScript)
       }
 
       if (sign.value) {
-        value = sign.value
+        witnessValue = sign.value
       }
 
       if (sign.witnessScript) {
         witnessScript = bscript.fromASM(sign.witnessScript)
       }
 
-      txb.sign(index, keyPair, redeemScript, sign.hashType, value, witnessScript)
+      if (useOldSignArgs) {
+        // DEPRECATED: v6 will remove this interface
+        txb.sign(index, keyPair, redeemScript, sign.hashType, witnessValue, witnessScript)
+      } else {
+        // prevOutScriptType is required, see /ts_src/transaction_builder.ts
+        // The PREVOUT_TYPES constant is a Set with all possible values.
+        txb.sign({
+          prevOutScriptType: sign.prevOutScriptType,
+          vin: index,
+          keyPair,
+          redeemScript,
+          hashType: sign.hashType,
+          witnessValue,
+          witnessScript,
+        })
+      }
 
       if (sign.stage) {
         const tx = txb.buildIncomplete()
@@ -48,7 +63,7 @@ function constructSign (f, txb) {
   return txb
 }
 
-function construct (f, dontSign) {
+function construct (f, dontSign, useOldSignArgs) {
   const network = NETWORKS[f.network]
   const txb = new TransactionBuilder(network)
 
@@ -84,545 +99,689 @@ function construct (f, dontSign) {
   })
 
   if (dontSign) return txb
-  return constructSign(f, txb)
+  return constructSign(f, txb, useOldSignArgs)
 }
 
-describe('TransactionBuilder', () => {
-  // constants
-  const keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex'))
-  const scripts = [
-    '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH',
-    '1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP'
-  ].map(x => {
-    return baddress.toOutputScript(x)
-  })
-  const txHash = Buffer.from('0e7cea811c0be9f73c0aca591034396e7264473fc25c1ca45195d7417b36cbe2', 'hex')
-
-  describe('fromTransaction', () => {
-    fixtures.valid.build.forEach(f => {
-      it('returns TransactionBuilder, with ' + f.description, () => {
-        const network = NETWORKS[f.network || 'bitcoin']
-
-        const tx = Transaction.fromHex(f.txHex)
-        const txb = TransactionBuilder.fromTransaction(tx, network)
-        const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
-
-        assert.strictEqual(txAfter.toHex(), f.txHex)
-        assert.strictEqual(txb.network, network)
-      })
+// TODO: Remove loop in v6
+for (const useOldSignArgs of [ false, true ]) {
+  // Search for "useOldSignArgs"
+  // to find the second part of this console.warn replace
+  let consoleWarn;
+  if (useOldSignArgs) {
+    consoleWarn = console.warn;
+    // Silence console.warn during these tests
+    console.warn = () => undefined;
+  }
+  describe(`TransactionBuilder: useOldSignArgs === ${useOldSignArgs}`, () => {
+    // constants
+    const keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex'))
+    const scripts = [
+      '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH',
+      '1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP'
+    ].map(x => {
+      return baddress.toOutputScript(x)
     })
+    const txHash = Buffer.from('0e7cea811c0be9f73c0aca591034396e7264473fc25c1ca45195d7417b36cbe2', 'hex')
 
-    fixtures.valid.fromTransaction.forEach(f => {
-      it('returns TransactionBuilder, with ' + f.description, () => {
-        const tx = new Transaction()
+    describe('fromTransaction', () => {
+      fixtures.valid.build.forEach(f => {
+        it('returns TransactionBuilder, with ' + f.description, () => {
+          const network = NETWORKS[f.network || 'bitcoin']
 
-        f.inputs.forEach(input => {
-          const txHash2 = Buffer.from(input.txId, 'hex').reverse()
+          const tx = Transaction.fromHex(f.txHex)
+          const txb = TransactionBuilder.fromTransaction(tx, network)
+          const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
 
-          tx.addInput(txHash2, input.vout, undefined, bscript.fromASM(input.scriptSig))
-        })
-
-        f.outputs.forEach(output => {
-          tx.addOutput(bscript.fromASM(output.script), output.value)
-        })
-
-        const txb = TransactionBuilder.fromTransaction(tx)
-        const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
-
-        txAfter.ins.forEach((input, i) => {
-          assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
-        })
-
-        txAfter.outs.forEach((output, i) => {
-          assert.strictEqual(bscript.toASM(output.script), f.outputs[i].script)
+          assert.strictEqual(txAfter.toHex(), f.txHex)
+          assert.strictEqual(txb.network, network)
         })
       })
-    })
 
-    fixtures.valid.fromTransactionSequential.forEach(f => {
-      it('with ' + f.description, () => {
-        const network = NETWORKS[f.network]
-        const tx = Transaction.fromHex(f.txHex)
-        const txb = TransactionBuilder.fromTransaction(tx, network)
+      fixtures.valid.fromTransaction.forEach(f => {
+        it('returns TransactionBuilder, with ' + f.description, () => {
+          const tx = new Transaction()
 
-        tx.ins.forEach((input, i) => {
-          assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSig)
-        })
+          f.inputs.forEach(input => {
+            const txHash2 = Buffer.from(input.txId, 'hex').reverse()
 
-        constructSign(f, txb)
-        const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
+            tx.addInput(txHash2, input.vout, undefined, bscript.fromASM(input.scriptSig))
+          })
 
-        txAfter.ins.forEach((input, i) => {
-          assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
-        })
+          f.outputs.forEach(output => {
+            tx.addOutput(bscript.fromASM(output.script), output.value)
+          })
 
-        assert.strictEqual(txAfter.toHex(), f.txHexAfter)
-      })
-    })
+          const txb = TransactionBuilder.fromTransaction(tx)
+          const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
 
-    it('classifies transaction inputs', () => {
-      const tx = Transaction.fromHex(fixtures.valid.classification.hex)
-      const txb = TransactionBuilder.fromTransaction(tx)
+          txAfter.ins.forEach((input, i) => {
+            assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
+          })
 
-      txb.__INPUTS.forEach(i => {
-        assert.strictEqual(i.prevOutType, 'scripthash')
-        assert.strictEqual(i.redeemScriptType, 'multisig')
-      })
-    })
-
-    fixtures.invalid.fromTransaction.forEach(f => {
-      it('throws ' + f.exception, () => {
-        const tx = Transaction.fromHex(f.txHex)
-
-        assert.throws(() => {
-          TransactionBuilder.fromTransaction(tx)
-        }, new RegExp(f.exception))
-      })
-    })
-  })
-
-  describe('addInput', () => {
-    let txb
-    beforeEach(() => {
-      txb = new TransactionBuilder()
-    })
-
-    it('accepts a txHash, index [and sequence number]', () => {
-      const vin = txb.addInput(txHash, 1, 54)
-      assert.strictEqual(vin, 0)
-
-      const txIn = txb.__TX.ins[0]
-      assert.strictEqual(txIn.hash, txHash)
-      assert.strictEqual(txIn.index, 1)
-      assert.strictEqual(txIn.sequence, 54)
-      assert.strictEqual(txb.__INPUTS[0].prevOutScript, undefined)
-    })
-
-    it('accepts a txHash, index [, sequence number and scriptPubKey]', () => {
-      const vin = txb.addInput(txHash, 1, 54, scripts[1])
-      assert.strictEqual(vin, 0)
-
-      const txIn = txb.__TX.ins[0]
-      assert.strictEqual(txIn.hash, txHash)
-      assert.strictEqual(txIn.index, 1)
-      assert.strictEqual(txIn.sequence, 54)
-      assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
-    })
-
-    it('accepts a prevTx, index [and sequence number]', () => {
-      const prevTx = new Transaction()
-      prevTx.addOutput(scripts[0], 0)
-      prevTx.addOutput(scripts[1], 1)
-
-      const vin = txb.addInput(prevTx, 1, 54)
-      assert.strictEqual(vin, 0)
-
-      const txIn = txb.__TX.ins[0]
-      assert.deepStrictEqual(txIn.hash, prevTx.getHash())
-      assert.strictEqual(txIn.index, 1)
-      assert.strictEqual(txIn.sequence, 54)
-      assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
-    })
-
-    it('returns the input index', () => {
-      assert.strictEqual(txb.addInput(txHash, 0), 0)
-      assert.strictEqual(txb.addInput(txHash, 1), 1)
-    })
-
-    it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
-      txb.addInput(txHash, 0)
-      txb.addOutput(scripts[0], 1000)
-      txb.sign(0, keyPair)
-
-      assert.throws(() => {
-        txb.addInput(txHash, 0)
-      }, /No, this would invalidate signatures/)
-    })
-  })
-
-  describe('addOutput', () => {
-    let txb
-    beforeEach(() => {
-      txb = new TransactionBuilder()
-    })
-
-    it('accepts an address string and value', () => {
-      const { address } = payments.p2pkh({ pubkey: keyPair.publicKey })
-      const vout = txb.addOutput(address, 1000)
-      assert.strictEqual(vout, 0)
-
-      const txout = txb.__TX.outs[0]
-      assert.deepStrictEqual(txout.script, scripts[0])
-      assert.strictEqual(txout.value, 1000)
-    })
-
-    it('accepts a ScriptPubKey and value', () => {
-      const vout = txb.addOutput(scripts[0], 1000)
-      assert.strictEqual(vout, 0)
-
-      const txout = txb.__TX.outs[0]
-      assert.deepStrictEqual(txout.script, scripts[0])
-      assert.strictEqual(txout.value, 1000)
-    })
-
-    it('throws if address is of the wrong network', () => {
-      assert.throws(() => {
-        txb.addOutput('2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9', 1000)
-      }, /2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9 has no matching Script/)
-    })
-
-    it('add second output after signed first input with SIGHASH_NONE', () => {
-      txb.addInput(txHash, 0)
-      txb.addOutput(scripts[0], 2000)
-      txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE)
-      assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
-    })
-
-    it('add first output after signed first input with SIGHASH_NONE', () => {
-      txb.addInput(txHash, 0)
-      txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE)
-      assert.strictEqual(txb.addOutput(scripts[0], 2000), 0)
-    })
-
-    it('add second output after signed first input with SIGHASH_SINGLE', () => {
-      txb.addInput(txHash, 0)
-      txb.addOutput(scripts[0], 2000)
-      txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE)
-      assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
-    })
-
-    it('add first output after signed first input with SIGHASH_SINGLE', () => {
-      txb.addInput(txHash, 0)
-      txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE)
-      assert.throws(() => {
-        txb.addOutput(scripts[0], 2000)
-      }, /No, this would invalidate signatures/)
-    })
-
-    it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
-      txb.addInput(txHash, 0)
-      txb.addOutput(scripts[0], 2000)
-      txb.sign(0, keyPair)
-
-      assert.throws(() => {
-        txb.addOutput(scripts[1], 9000)
-      }, /No, this would invalidate signatures/)
-    })
-  })
-
-  describe('setLockTime', () => {
-    it('throws if if there exist any scriptSigs', () => {
-      const txb = new TransactionBuilder()
-      txb.addInput(txHash, 0)
-      txb.addOutput(scripts[0], 100)
-      txb.sign(0, keyPair)
-
-      assert.throws(() => {
-        txb.setLockTime(65535)
-      }, /No, this would invalidate signatures/)
-    })
-  })
-
-  describe('sign', () => {
-    it('supports the alternative abstract interface { publicKey, sign }', () => {
-      const keyPair = {
-        publicKey: ECPair.makeRandom({ rng: () => { return Buffer.alloc(32, 1) } }).publicKey,
-        sign: hash => { return Buffer.alloc(64, 0x5f) }
-      }
-
-      const txb = new TransactionBuilder()
-      txb.setVersion(1)
-      txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
-      txb.addOutput('1111111111111111111114oLvT2', 100000)
-      txb.sign(0, keyPair)
-      assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a47304402205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f02205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0121031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
-    })
-
-    it('supports low R signature signing', () => {
-      let txb = new TransactionBuilder()
-      txb.setVersion(1)
-      txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
-      txb.addOutput('1111111111111111111114oLvT2', 100000)
-      txb.sign(0, keyPair)
-      // high R
-      assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006b483045022100b872677f35c9c14ad9c41d83649fb049250f32574e0b2547d67e209ed14ff05d022059b36ad058be54e887a1a311d5c393cb4941f6b93a0b090845ec67094de8972b01210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
-
-      txb = new TransactionBuilder()
-      txb.setVersion(1)
-      txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
-      txb.addOutput('1111111111111111111114oLvT2', 100000)
-      txb.setLowR()
-      txb.sign(0, keyPair)
-      // low R
-      assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a473044022012a601efa8756ebe83e9ac7a7db061c3147e3b49d8be67685799fe51a4c8c62f02204d568d301d5ce14af390d566d4fd50e7b8ee48e71ec67786c029e721194dae3601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
-    })
-
-    fixtures.invalid.sign.forEach(f => {
-      it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
-        const txb = construct(f, true)
-
-        let threw = false
-        f.inputs.forEach((input, index) => {
-          input.signs.forEach(sign => {
-            const keyPairNetwork = NETWORKS[sign.network || f.network]
-            const keyPair2 = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
-            let redeemScript
-            let witnessScript
-
-            if (sign.redeemScript) {
-              redeemScript = bscript.fromASM(sign.redeemScript)
-            }
-
-            if (sign.witnessScript) {
-              witnessScript = bscript.fromASM(sign.witnessScript)
-            }
-
-            if (sign.throws) {
-              assert.throws(() => {
-                txb.sign(index, keyPair2, redeemScript, sign.hashType, sign.value, witnessScript)
-              }, new RegExp(f.exception))
-              threw = true
-            } else {
-              txb.sign(index, keyPair2, redeemScript, sign.hashType, sign.value, witnessScript)
-            }
+          txAfter.outs.forEach((output, i) => {
+            assert.strictEqual(bscript.toASM(output.script), f.outputs[i].script)
           })
         })
-
-        assert.strictEqual(threw, true)
       })
-    })
-  })
 
-  describe('build', () => {
-    fixtures.valid.build.forEach(f => {
-      it('builds "' + f.description + '"', () => {
-        const txb = construct(f)
-        const tx = f.incomplete ? txb.buildIncomplete() : txb.build()
+      fixtures.valid.fromTransactionSequential.forEach(f => {
+        it('with ' + f.description, () => {
+          const network = NETWORKS[f.network]
+          const tx = Transaction.fromHex(f.txHex)
+          const txb = TransactionBuilder.fromTransaction(tx, network)
 
-        assert.strictEqual(tx.toHex(), f.txHex)
+          tx.ins.forEach((input, i) => {
+            assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSig)
+          })
+
+          constructSign(f, txb, useOldSignArgs)
+          const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
+
+          txAfter.ins.forEach((input, i) => {
+            assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
+          })
+
+          assert.strictEqual(txAfter.toHex(), f.txHexAfter)
+        })
       })
-    })
 
-    // TODO: remove duplicate test code
-    fixtures.invalid.build.forEach(f => {
-      describe('for ' + (f.description || f.exception), () => {
+      it('classifies transaction inputs', () => {
+        const tx = Transaction.fromHex(fixtures.valid.classification.hex)
+        const txb = TransactionBuilder.fromTransaction(tx)
+
+        txb.__INPUTS.forEach(i => {
+          assert.strictEqual(i.prevOutType, 'scripthash')
+          assert.strictEqual(i.redeemScriptType, 'multisig')
+        })
+      })
+
+      fixtures.invalid.fromTransaction.forEach(f => {
         it('throws ' + f.exception, () => {
-          assert.throws(() => {
-            let txb
-            if (f.txHex) {
-              txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
-            } else {
-              txb = construct(f)
-            }
+          const tx = Transaction.fromHex(f.txHex)
 
-            txb.build()
+          assert.throws(() => {
+            TransactionBuilder.fromTransaction(tx)
           }, new RegExp(f.exception))
         })
+      })
+    })
 
-        // if throws on incomplete too, enforce that
-        if (f.incomplete) {
+    describe('addInput', () => {
+      let txb
+      beforeEach(() => {
+        txb = new TransactionBuilder()
+      })
+
+      it('accepts a txHash, index [and sequence number]', () => {
+        const vin = txb.addInput(txHash, 1, 54)
+        assert.strictEqual(vin, 0)
+
+        const txIn = txb.__TX.ins[0]
+        assert.strictEqual(txIn.hash, txHash)
+        assert.strictEqual(txIn.index, 1)
+        assert.strictEqual(txIn.sequence, 54)
+        assert.strictEqual(txb.__INPUTS[0].prevOutScript, undefined)
+      })
+
+      it('accepts a txHash, index [, sequence number and scriptPubKey]', () => {
+        const vin = txb.addInput(txHash, 1, 54, scripts[1])
+        assert.strictEqual(vin, 0)
+
+        const txIn = txb.__TX.ins[0]
+        assert.strictEqual(txIn.hash, txHash)
+        assert.strictEqual(txIn.index, 1)
+        assert.strictEqual(txIn.sequence, 54)
+        assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
+      })
+
+      it('accepts a prevTx, index [and sequence number]', () => {
+        const prevTx = new Transaction()
+        prevTx.addOutput(scripts[0], 0)
+        prevTx.addOutput(scripts[1], 1)
+
+        const vin = txb.addInput(prevTx, 1, 54)
+        assert.strictEqual(vin, 0)
+
+        const txIn = txb.__TX.ins[0]
+        assert.deepStrictEqual(txIn.hash, prevTx.getHash())
+        assert.strictEqual(txIn.index, 1)
+        assert.strictEqual(txIn.sequence, 54)
+        assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
+      })
+
+      it('returns the input index', () => {
+        assert.strictEqual(txb.addInput(txHash, 0), 0)
+        assert.strictEqual(txb.addInput(txHash, 1), 1)
+      })
+
+      it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
+        txb.addInput(txHash, 0)
+        txb.addOutput(scripts[0], 1000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+
+        assert.throws(() => {
+          txb.addInput(txHash, 0)
+        }, /No, this would invalidate signatures/)
+      })
+    })
+
+    describe('addOutput', () => {
+      let txb
+      beforeEach(() => {
+        txb = new TransactionBuilder()
+      })
+
+      it('accepts an address string and value', () => {
+        const { address } = payments.p2pkh({ pubkey: keyPair.publicKey })
+        const vout = txb.addOutput(address, 1000)
+        assert.strictEqual(vout, 0)
+
+        const txout = txb.__TX.outs[0]
+        assert.deepStrictEqual(txout.script, scripts[0])
+        assert.strictEqual(txout.value, 1000)
+      })
+
+      it('accepts a ScriptPubKey and value', () => {
+        const vout = txb.addOutput(scripts[0], 1000)
+        assert.strictEqual(vout, 0)
+
+        const txout = txb.__TX.outs[0]
+        assert.deepStrictEqual(txout.script, scripts[0])
+        assert.strictEqual(txout.value, 1000)
+      })
+
+      it('throws if address is of the wrong network', () => {
+        assert.throws(() => {
+          txb.addOutput('2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9', 1000)
+        }, /2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9 has no matching Script/)
+      })
+
+      it('add second output after signed first input with SIGHASH_NONE', () => {
+        txb.addInput(txHash, 0)
+        txb.addOutput(scripts[0], 2000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+          hashType: Transaction.SIGHASH_NONE,
+        })
+        assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
+      })
+
+      it('add first output after signed first input with SIGHASH_NONE', () => {
+        txb.addInput(txHash, 0)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+          hashType: Transaction.SIGHASH_NONE,
+        })
+        assert.strictEqual(txb.addOutput(scripts[0], 2000), 0)
+      })
+
+      it('add second output after signed first input with SIGHASH_SINGLE', () => {
+        txb.addInput(txHash, 0)
+        txb.addOutput(scripts[0], 2000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+          hashType: Transaction.SIGHASH_SINGLE,
+        })
+        assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
+      })
+
+      it('add first output after signed first input with SIGHASH_SINGLE', () => {
+        txb.addInput(txHash, 0)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+          hashType: Transaction.SIGHASH_SINGLE,
+        })
+        assert.throws(() => {
+          txb.addOutput(scripts[0], 2000)
+        }, /No, this would invalidate signatures/)
+      })
+
+      it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
+        txb.addInput(txHash, 0)
+        txb.addOutput(scripts[0], 2000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+
+        assert.throws(() => {
+          txb.addOutput(scripts[1], 9000)
+        }, /No, this would invalidate signatures/)
+      })
+    })
+
+    describe('setLockTime', () => {
+      it('throws if if there exist any scriptSigs', () => {
+        const txb = new TransactionBuilder()
+        txb.addInput(txHash, 0)
+        txb.addOutput(scripts[0], 100)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+
+        assert.throws(() => {
+          txb.setLockTime(65535)
+        }, /No, this would invalidate signatures/)
+      })
+    })
+
+    describe('sign', () => {
+      it('supports the alternative abstract interface { publicKey, sign }', () => {
+        const keyPair = {
+          publicKey: ECPair.makeRandom({ rng: () => { return Buffer.alloc(32, 1) } }).publicKey,
+          sign: hash => { return Buffer.alloc(64, 0x5f) }
+        }
+
+        const txb = new TransactionBuilder()
+        txb.setVersion(1)
+        txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
+        txb.addOutput('1111111111111111111114oLvT2', 100000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+        assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a47304402205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f02205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0121031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
+      })
+
+      it('supports low R signature signing', () => {
+        let txb = new TransactionBuilder()
+        txb.setVersion(1)
+        txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
+        txb.addOutput('1111111111111111111114oLvT2', 100000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+        // high R
+        assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006b483045022100b872677f35c9c14ad9c41d83649fb049250f32574e0b2547d67e209ed14ff05d022059b36ad058be54e887a1a311d5c393cb4941f6b93a0b090845ec67094de8972b01210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
+
+        txb = new TransactionBuilder()
+        txb.setVersion(1)
+        txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
+        txb.addOutput('1111111111111111111114oLvT2', 100000)
+        txb.setLowR()
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+        // low R
+        assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a473044022012a601efa8756ebe83e9ac7a7db061c3147e3b49d8be67685799fe51a4c8c62f02204d568d301d5ce14af390d566d4fd50e7b8ee48e71ec67786c029e721194dae3601210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
+      })
+
+      it('fails when missing required arguments', () => {
+        let txb = new TransactionBuilder()
+        txb.setVersion(1)
+        txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
+        txb.addOutput('1111111111111111111114oLvT2', 100000)
+        assert.throws(() => {
+          txb.sign()
+        }, /TransactionBuilder sign first arg must be TxbSignArg or number/)
+        assert.throws(() => {
+          txb.sign({
+            prevOutScriptType: 'p2pkh',
+            vin: 1,
+            keyPair,
+          })
+        }, /No input at index: 1/)
+        assert.throws(() => {
+          txb.sign({
+            prevOutScriptType: 'p2pkh',
+            keyPair,
+          })
+        }, /sign must include vin parameter as Number \(input index\)/)
+        assert.throws(() => {
+          txb.sign({
+            prevOutScriptType: 'p2pkh',
+            vin: 0,
+            keyPair: {},
+          })
+        }, /sign must include keyPair parameter as Signer interface/)
+        assert.throws(() => {
+          txb.sign({
+            prevOutScriptType: 'p2pkh',
+            vin: 0,
+            keyPair,
+            hashType: 'string',
+          })
+        }, /sign hashType parameter must be a number/)
+        if (useOldSignArgs) {
+          assert.throws(() => {
+            txb.sign(0)
+          }, /sign requires keypair/)
+        }
+      })
+
+      fixtures.invalid.sign.forEach(f => {
+        it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
+          const txb = construct(f, true)
+
+          let threw = false
+          f.inputs.forEach((input, index) => {
+            input.signs.forEach(sign => {
+              const keyPairNetwork = NETWORKS[sign.network || f.network]
+              const keyPair2 = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
+              let redeemScript
+              let witnessScript
+
+              if (sign.redeemScript) {
+                redeemScript = bscript.fromASM(sign.redeemScript)
+              }
+
+              if (sign.witnessScript) {
+                witnessScript = bscript.fromASM(sign.witnessScript)
+              }
+
+              if (sign.throws) {
+                assert.throws(() => {
+                  txb.sign({
+                    prevOutScriptType: sign.prevOutScriptType,
+                    vin: index,
+                    keyPair: keyPair2,
+                    redeemScript,
+                    hashType: sign.hashType,
+                    witnessValue: sign.value,
+                    witnessScript,
+                  })
+                }, new RegExp(f.exception))
+                threw = true
+              } else {
+                txb.sign({
+                  prevOutScriptType: sign.prevOutScriptType,
+                  vin: index,
+                  keyPair: keyPair2,
+                  redeemScript,
+                  hashType: sign.hashType,
+                  witnessValue: sign.value,
+                  witnessScript,
+                })
+              }
+            })
+          })
+
+          assert.strictEqual(threw, true)
+        })
+      })
+    })
+
+    describe('build', () => {
+      fixtures.valid.build.forEach(f => {
+        it('builds "' + f.description + '"', () => {
+          const txb = construct(f, undefined, useOldSignArgs)
+          const tx = f.incomplete ? txb.buildIncomplete() : txb.build()
+
+          assert.strictEqual(tx.toHex(), f.txHex)
+        })
+      })
+
+      // TODO: remove duplicate test code
+      fixtures.invalid.build.forEach(f => {
+        describe('for ' + (f.description || f.exception), () => {
           it('throws ' + f.exception, () => {
             assert.throws(() => {
               let txb
               if (f.txHex) {
                 txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
               } else {
-                txb = construct(f)
+                txb = construct(f, undefined, useOldSignArgs)
+              }
+
+              txb.build()
+            }, new RegExp(f.exception))
+          })
+
+          // if throws on incomplete too, enforce that
+          if (f.incomplete) {
+            it('throws ' + f.exception, () => {
+              assert.throws(() => {
+                let txb
+                if (f.txHex) {
+                  txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
+                } else {
+                  txb = construct(f, undefined, useOldSignArgs)
+                }
+
+                txb.buildIncomplete()
+              }, new RegExp(f.exception))
+            })
+          } else {
+            it('does not throw if buildIncomplete', () => {
+              let txb
+              if (f.txHex) {
+                txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
+              } else {
+                txb = construct(f, undefined, useOldSignArgs)
               }
 
               txb.buildIncomplete()
-            }, new RegExp(f.exception))
-          })
-        } else {
-          it('does not throw if buildIncomplete', () => {
-            let txb
-            if (f.txHex) {
-              txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
-            } else {
-              txb = construct(f)
-            }
+            })
+          }
+        })
+      })
 
-            txb.buildIncomplete()
+      it('for incomplete with 0 signatures', () => {
+        const randomTxData = '0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000'
+        const randomAddress = '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'
+
+        const randomTx = Transaction.fromHex(randomTxData)
+        let tx = new TransactionBuilder()
+        tx.addInput(randomTx, 0)
+        tx.addOutput(randomAddress, 1000)
+        tx = tx.buildIncomplete()
+        assert(tx)
+      })
+
+      it('for incomplete P2SH with 0 signatures', () => {
+        const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000017a91471a8ec07ff69c6c4fee489184c462a9b1b9237488700000000', 'hex') // arbitrary P2SH input
+        const inpTx = Transaction.fromBuffer(inp)
+
+        const txb = new TransactionBuilder(NETWORKS.testnet)
+        txb.addInput(inpTx, 0)
+        txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
+
+        txb.buildIncomplete()
+      })
+
+      it('for incomplete P2WPKH with 0 signatures', () => {
+        const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a8040000001600141a15805e1f4040c9f68ccc887fca2e63547d794b00000000', 'hex')
+        const inpTx = Transaction.fromBuffer(inp)
+
+        const txb = new TransactionBuilder(NETWORKS.testnet)
+        txb.addInput(inpTx, 0)
+        txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
+
+        txb.buildIncomplete()
+      })
+
+      it('for incomplete P2WSH with 0 signatures', () => {
+        const inpTx = Transaction.fromBuffer(Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000022002072df76fcc0b231b94bdf7d8c25d7eef4716597818d211e19ade7813bff7a250200000000', 'hex'))
+
+        const txb = new TransactionBuilder(NETWORKS.testnet)
+        txb.addInput(inpTx, 0)
+        txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
+
+        txb.buildIncomplete()
+      })
+    })
+
+    describe('multisig', () => {
+      fixtures.valid.multisig.forEach(f => {
+        it(f.description, () => {
+          const network = NETWORKS[f.network]
+          let txb = construct(f, true)
+          let tx
+
+          f.inputs.forEach((input, i) => {
+            const redeemScript = bscript.fromASM(input.redeemScript)
+
+            input.signs.forEach(sign => {
+              // rebuild the transaction each-time after the first
+              if (tx) {
+                // manually override the scriptSig?
+                if (sign.scriptSigBefore) {
+                  tx.ins[i].script = bscript.fromASM(sign.scriptSigBefore)
+                }
+
+                // rebuild
+                txb = TransactionBuilder.fromTransaction(tx, network)
+              }
+
+              const keyPair2 = ECPair.fromWIF(sign.keyPair, network)
+              txb.sign({
+                prevOutScriptType: sign.prevOutScriptType,
+                vin: i,
+                keyPair: keyPair2,
+                redeemScript,
+                hashType: sign.hashType,
+              })
+
+              // update the tx
+              tx = txb.buildIncomplete()
+
+              // now verify the serialized scriptSig is as expected
+              assert.strictEqual(bscript.toASM(tx.ins[i].script), sign.scriptSig)
+            })
           })
+
+          tx = txb.build()
+          assert.strictEqual(tx.toHex(), f.txHex)
+        })
+      })
+    })
+
+    describe('various edge case', () => {
+      const network = NETWORKS.testnet
+
+      it('should warn of high fee for segwit transaction based on VSize, not Size', () => {
+        const rawtx = '01000000000104fdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a' +
+        '1df90000000000fffffffffdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a1df9' +
+        '0100000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca40000' +
+        '000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca401000000' +
+        '00ffffffff0100040000000000001976a914cf307285359ab7ef6a2daa0522c7908ddf5fe7a988ac024730' +
+        '440220113324438816338406841775e079b04c50d04f241da652a4035b1017ea1ecf5502205802191eb49c' +
+        '54bf2a5667aea72e51c3ca92085efc60f12d1ebda3a64aff343201210283409659355b6d1cc3c32decd5d5' +
+        '61abaac86c37a353b52895a5e6c196d6f44802483045022100dc2892874e6d8708e3f5a058c5c9263cdf03' +
+        '969492270f89ee4933caf6daf8bb0220391dfe61a002709b63b9d64422d3db09b727839d1287e10a128a5d' +
+        'b52a82309301210283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448024830' +
+        '450221009e3ed3a6ae93a018f443257b43e47b55cf7f7f3547d8807178072234686b22160220576121cfe6' +
+        '77c7eddf5575ea0a7c926247df6eca723c4f85df306e8bc08ea2df01210283409659355b6d1cc3c32decd5' +
+        'd561abaac86c37a353b52895a5e6c196d6f44802473044022007be81ffd4297441ab10e740fc9bab9545a2' +
+        '194a565cd6aa4cc38b8eaffa343402201c5b4b61d73fa38e49c1ee68cc0e6dfd2f5dae453dd86eb142e87a' +
+        '0bafb1bc8401210283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f44800000000'
+        const txb = TransactionBuilder.fromTransaction(Transaction.fromHex(rawtx))
+        txb.__INPUTS[0].value = 241530
+        txb.__INPUTS[1].value = 241530
+        txb.__INPUTS[2].value = 248920
+        txb.__INPUTS[3].value = 248920
+
+        assert.throws(() => {
+          txb.build()
+        }, new RegExp('Transaction has absurd fees'))
+      })
+
+      it('should classify witness inputs with witness = true during multisigning', () => {
+        const keyPair = ECPair.fromWIF('cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS', network)
+        const witnessScript = Buffer.from('522102bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e22102d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea1952ae', 'hex')
+        const redeemScript = Buffer.from('002024376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af', 'hex')
+        const scriptPubKey = Buffer.from('a914b64f1a3eacc1c8515592a6f10457e8ff90e4db6a87', 'hex')
+        const txb = new TransactionBuilder(network)
+        txb.setVersion(1)
+        txb.addInput('a4696c4b0cd27ec2e173ab1fa7d1cc639a98ee237cec95a77ca7ff4145791529', 1, 0xffffffff, scriptPubKey)
+        txb.addOutput(scriptPubKey, 99000)
+        txb.sign({
+          prevOutScriptType: 'p2sh-p2wsh-p2ms',
+          vin: 0,
+          keyPair,
+          redeemScript,
+          witnessValue: 100000,
+          witnessScript,
+        })
+
+        // 2-of-2 signed only once
+        const tx = txb.buildIncomplete()
+
+        // Only input is segwit, so txid should be accurate with the final tx
+        assert.strictEqual(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
+
+        const txHex = tx.toHex()
+        TransactionBuilder.fromTransaction(Transaction.fromHex(txHex))
+      })
+
+      it('should handle badly pre-filled OP_0s', () => {
+        // OP_0 is used where a signature is missing
+        const redeemScripSig = bscript.fromASM('OP_0 OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
+        const redeemScript = bscript.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
+
+        const tx = new Transaction()
+        tx.addInput(Buffer.from('cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f07149', 'hex'), 0, undefined, redeemScripSig)
+        tx.addOutput(Buffer.from('76a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac', 'hex'), 1000)
+
+        // now import the Transaction
+        const txb = TransactionBuilder.fromTransaction(tx, NETWORKS.testnet)
+
+        const keyPair2 = ECPair.fromWIF('91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', network)
+        txb.sign({
+          prevOutScriptType: 'p2sh-p2ms',
+          vin: 0,
+          keyPair: keyPair2,
+          redeemScript,
+        })
+
+        const tx2 = txb.build()
+        assert.strictEqual(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
+        assert.strictEqual(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
+      })
+
+      it('should not classify blank scripts as nonstandard', () => {
+        let txb = new TransactionBuilder()
+        txb.setVersion(1)
+        txb.addInput('aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31', 0)
+
+        const incomplete = txb.buildIncomplete().toHex()
+        const keyPair = ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
+
+        // sign, as expected
+        txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+        const txId = txb.build().getId()
+        assert.strictEqual(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
+
+        // and, repeat
+        txb = TransactionBuilder.fromTransaction(Transaction.fromHex(incomplete))
+        txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
+        txb.sign({
+          prevOutScriptType: 'p2pkh',
+          vin: 0,
+          keyPair,
+        })
+        const txId2 = txb.build().getId()
+        assert.strictEqual(txId, txId2)
+        // TODO: Remove me in v6
+        if (useOldSignArgs) {
+          console.warn = consoleWarn;
         }
       })
     })
-
-    it('for incomplete with 0 signatures', () => {
-      const randomTxData = '0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000'
-      const randomAddress = '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'
-
-      const randomTx = Transaction.fromHex(randomTxData)
-      let tx = new TransactionBuilder()
-      tx.addInput(randomTx, 0)
-      tx.addOutput(randomAddress, 1000)
-      tx = tx.buildIncomplete()
-      assert(tx)
-    })
-
-    it('for incomplete P2SH with 0 signatures', () => {
-      const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000017a91471a8ec07ff69c6c4fee489184c462a9b1b9237488700000000', 'hex') // arbitrary P2SH input
-      const inpTx = Transaction.fromBuffer(inp)
-
-      const txb = new TransactionBuilder(NETWORKS.testnet)
-      txb.addInput(inpTx, 0)
-      txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
-
-      txb.buildIncomplete()
-    })
-
-    it('for incomplete P2WPKH with 0 signatures', () => {
-      const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a8040000001600141a15805e1f4040c9f68ccc887fca2e63547d794b00000000', 'hex')
-      const inpTx = Transaction.fromBuffer(inp)
-
-      const txb = new TransactionBuilder(NETWORKS.testnet)
-      txb.addInput(inpTx, 0)
-      txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
-
-      txb.buildIncomplete()
-    })
-
-    it('for incomplete P2WSH with 0 signatures', () => {
-      const inpTx = Transaction.fromBuffer(Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000022002072df76fcc0b231b94bdf7d8c25d7eef4716597818d211e19ade7813bff7a250200000000', 'hex'))
-
-      const txb = new TransactionBuilder(NETWORKS.testnet)
-      txb.addInput(inpTx, 0)
-      txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
-
-      txb.buildIncomplete()
-    })
   })
-
-  describe('multisig', () => {
-    fixtures.valid.multisig.forEach(f => {
-      it(f.description, () => {
-        const network = NETWORKS[f.network]
-        let txb = construct(f, true)
-        let tx
-
-        f.inputs.forEach((input, i) => {
-          const redeemScript = bscript.fromASM(input.redeemScript)
-
-          input.signs.forEach(sign => {
-            // rebuild the transaction each-time after the first
-            if (tx) {
-              // manually override the scriptSig?
-              if (sign.scriptSigBefore) {
-                tx.ins[i].script = bscript.fromASM(sign.scriptSigBefore)
-              }
-
-              // rebuild
-              txb = TransactionBuilder.fromTransaction(tx, network)
-            }
-
-            const keyPair2 = ECPair.fromWIF(sign.keyPair, network)
-            txb.sign(i, keyPair2, redeemScript, sign.hashType)
-
-            // update the tx
-            tx = txb.buildIncomplete()
-
-            // now verify the serialized scriptSig is as expected
-            assert.strictEqual(bscript.toASM(tx.ins[i].script), sign.scriptSig)
-          })
-        })
-
-        tx = txb.build()
-        assert.strictEqual(tx.toHex(), f.txHex)
-      })
-    })
-  })
-
-  describe('various edge case', () => {
-    const network = NETWORKS.testnet
-
-    it('should warn of high fee for segwit transaction based on VSize, not Size', () => {
-      const rawtx = '01000000000104fdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a' +
-      '1df90000000000fffffffffdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a1df9' +
-      '0100000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca40000' +
-      '000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca401000000' +
-      '00ffffffff0100040000000000001976a914cf307285359ab7ef6a2daa0522c7908ddf5fe7a988ac024730' +
-      '440220113324438816338406841775e079b04c50d04f241da652a4035b1017ea1ecf5502205802191eb49c' +
-      '54bf2a5667aea72e51c3ca92085efc60f12d1ebda3a64aff343201210283409659355b6d1cc3c32decd5d5' +
-      '61abaac86c37a353b52895a5e6c196d6f44802483045022100dc2892874e6d8708e3f5a058c5c9263cdf03' +
-      '969492270f89ee4933caf6daf8bb0220391dfe61a002709b63b9d64422d3db09b727839d1287e10a128a5d' +
-      'b52a82309301210283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f448024830' +
-      '450221009e3ed3a6ae93a018f443257b43e47b55cf7f7f3547d8807178072234686b22160220576121cfe6' +
-      '77c7eddf5575ea0a7c926247df6eca723c4f85df306e8bc08ea2df01210283409659355b6d1cc3c32decd5' +
-      'd561abaac86c37a353b52895a5e6c196d6f44802473044022007be81ffd4297441ab10e740fc9bab9545a2' +
-      '194a565cd6aa4cc38b8eaffa343402201c5b4b61d73fa38e49c1ee68cc0e6dfd2f5dae453dd86eb142e87a' +
-      '0bafb1bc8401210283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f44800000000'
-      const txb = TransactionBuilder.fromTransaction(Transaction.fromHex(rawtx))
-      txb.__INPUTS[0].value = 241530
-      txb.__INPUTS[1].value = 241530
-      txb.__INPUTS[2].value = 248920
-      txb.__INPUTS[3].value = 248920
-
-      assert.throws(() => {
-        txb.build()
-      }, new RegExp('Transaction has absurd fees'))
-    })
-
-    it('should classify witness inputs with witness = true during multisigning', () => {
-      const keyPair = ECPair.fromWIF('cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS', network)
-      const witnessScript = Buffer.from('522102bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e22102d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea1952ae', 'hex')
-      const redeemScript = Buffer.from('002024376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af', 'hex')
-      const scriptPubKey = Buffer.from('a914b64f1a3eacc1c8515592a6f10457e8ff90e4db6a87', 'hex')
-      const txb = new TransactionBuilder(network)
-      txb.setVersion(1)
-      txb.addInput('a4696c4b0cd27ec2e173ab1fa7d1cc639a98ee237cec95a77ca7ff4145791529', 1, 0xffffffff, scriptPubKey)
-      txb.addOutput(scriptPubKey, 99000)
-      txb.sign(0, keyPair, redeemScript, null, 100000, witnessScript)
-
-      // 2-of-2 signed only once
-      const tx = txb.buildIncomplete()
-
-      // Only input is segwit, so txid should be accurate with the final tx
-      assert.strictEqual(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
-
-      const txHex = tx.toHex()
-      TransactionBuilder.fromTransaction(Transaction.fromHex(txHex))
-    })
-
-    it('should handle badly pre-filled OP_0s', () => {
-      // OP_0 is used where a signature is missing
-      const redeemScripSig = bscript.fromASM('OP_0 OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
-      const redeemScript = bscript.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
-
-      const tx = new Transaction()
-      tx.addInput(Buffer.from('cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f07149', 'hex'), 0, undefined, redeemScripSig)
-      tx.addOutput(Buffer.from('76a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac', 'hex'), 1000)
-
-      // now import the Transaction
-      const txb = TransactionBuilder.fromTransaction(tx, NETWORKS.testnet)
-
-      const keyPair2 = ECPair.fromWIF('91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', network)
-      txb.sign(0, keyPair2, redeemScript)
-
-      const tx2 = txb.build()
-      assert.strictEqual(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
-      assert.strictEqual(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
-    })
-
-    it('should not classify blank scripts as nonstandard', () => {
-      let txb = new TransactionBuilder()
-      txb.setVersion(1)
-      txb.addInput('aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31', 0)
-
-      const incomplete = txb.buildIncomplete().toHex()
-      const keyPair = ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
-
-      // sign, as expected
-      txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
-      txb.sign(0, keyPair)
-      const txId = txb.build().getId()
-      assert.strictEqual(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
-
-      // and, repeat
-      txb = TransactionBuilder.fromTransaction(Transaction.fromHex(incomplete))
-      txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
-      txb.sign(0, keyPair)
-      const txId2 = txb.build().getId()
-      assert.strictEqual(txId, txId2)
-    })
-  })
-})
+}
diff --git a/ts_src/ecpair.ts b/ts_src/ecpair.ts
index 3d74433..c951f76 100644
--- a/ts_src/ecpair.ts
+++ b/ts_src/ecpair.ts
@@ -19,15 +19,26 @@ interface ECPairOptions {
   rng?(arg0: number): Buffer;
 }
 
-export interface ECPairInterface {
+export interface Signer {
+  publicKey: Buffer;
+  network?: Network;
+  sign(hash: Buffer, lowR?: boolean): Buffer;
+  getPublicKey?(): Buffer;
+}
+
+export interface SignerAsync {
+  publicKey: Buffer;
+  network?: Network;
+  sign(hash: Buffer, lowR?: boolean): Promise<Buffer>;
+  getPublicKey?(): Buffer;
+}
+
+export interface ECPairInterface extends Signer {
   compressed: boolean;
   network: Network;
-  publicKey: Buffer;
   privateKey?: Buffer;
   toWIF(): string;
-  sign(hash: Buffer, lowR?: boolean): Buffer;
   verify(hash: Buffer, signature: Buffer): boolean;
-  getPublicKey?(): Buffer;
 }
 
 class ECPair implements ECPairInterface {
diff --git a/ts_src/index.ts b/ts_src/index.ts
index 1068839..4f2d498 100644
--- a/ts_src/index.ts
+++ b/ts_src/index.ts
@@ -14,7 +14,7 @@ export { Transaction } from './transaction';
 export { TransactionBuilder } from './transaction_builder';
 
 export { BIP32Interface } from 'bip32';
-export { ECPairInterface } from './ecpair';
+export { ECPairInterface, Signer, SignerAsync } from './ecpair';
 export { Network } from './networks';
 export { Payment, PaymentOpts, Stack, StackElement } from './payments';
 export { OpCode } from './script';
diff --git a/ts_src/transaction_builder.ts b/ts_src/transaction_builder.ts
index 0665719..c486285 100644
--- a/ts_src/transaction_builder.ts
+++ b/ts_src/transaction_builder.ts
@@ -2,7 +2,7 @@ import * as baddress from './address';
 import { reverseBuffer } from './bufferutils';
 import * as classify from './classify';
 import * as bcrypto from './crypto';
-import { ECPairInterface } from './ecpair';
+import { Signer } from './ecpair';
 import * as ECPair from './ecpair';
 import { Network } from './networks';
 import * as networks from './networks';
@@ -16,6 +16,27 @@ const typeforce = require('typeforce');
 
 const SCRIPT_TYPES = classify.types;
 
+const PREVOUT_TYPES: Set<string> = new Set([
+  // Raw
+  'p2pkh',
+  'p2pk',
+  'p2wpkh',
+  'p2ms',
+  // P2SH wrapped
+  'p2sh-p2pkh',
+  'p2sh-p2pk',
+  'p2sh-p2wpkh',
+  'p2sh-p2ms',
+  // P2WSH wrapped
+  'p2wsh-p2pkh',
+  'p2wsh-p2pk',
+  'p2wsh-p2ms',
+  // P2SH-P2WSH wrapper
+  'p2sh-p2wsh-p2pkh',
+  'p2sh-p2wsh-p2pk',
+  'p2sh-p2wsh-p2ms',
+]);
+
 type MaybeBuffer = Buffer | undefined;
 type TxbSignatures = Buffer[] | MaybeBuffer[];
 type TxbPubkeys = MaybeBuffer[];
@@ -50,6 +71,24 @@ interface TxbOutput {
   maxSignatures?: number;
 }
 
+interface TxbSignArg {
+  prevOutScriptType: string;
+  vin: number;
+  keyPair: Signer;
+  redeemScript?: Buffer;
+  hashType?: number;
+  witnessValue?: number;
+  witnessScript?: Buffer;
+}
+
+function tfMessage(type: any, value: any, message: string): void {
+  try {
+    typeforce(type, value);
+  } catch (err) {
+    throw new Error(message);
+  }
+}
+
 function txIsString(tx: Buffer | string | Transaction): tx is string {
   return typeof tx === 'string' || tx instanceof String;
 }
@@ -197,92 +236,28 @@ export class TransactionBuilder {
   }
 
   sign(
-    vin: number,
-    keyPair: ECPairInterface,
+    signParams: number | TxbSignArg,
+    keyPair?: Signer,
     redeemScript?: Buffer,
     hashType?: number,
     witnessValue?: number,
     witnessScript?: Buffer,
   ): void {
-    // TODO: remove keyPair.network matching in 4.0.0
-    if (keyPair.network && keyPair.network !== this.network)
-      throw new TypeError('Inconsistent network');
-    if (!this.__INPUTS[vin]) throw new Error('No input at index: ' + vin);
-
-    hashType = hashType || Transaction.SIGHASH_ALL;
-    if (this.__needsOutputs(hashType))
-      throw new Error('Transaction needs outputs');
-
-    const input = this.__INPUTS[vin];
-
-    // if redeemScript was previously provided, enforce consistency
-    if (
-      input.redeemScript !== undefined &&
-      redeemScript &&
-      !input.redeemScript.equals(redeemScript)
-    ) {
-      throw new Error('Inconsistent redeemScript');
-    }
-
-    const ourPubKey = keyPair.publicKey || keyPair.getPublicKey!();
-    if (!canSign(input)) {
-      if (witnessValue !== undefined) {
-        if (input.value !== undefined && input.value !== witnessValue)
-          throw new Error('Input did not match witnessValue');
-        typeforce(types.Satoshi, witnessValue);
-        input.value = witnessValue;
-      }
-
-      if (!canSign(input)) {
-        const prepared = prepareInput(
-          input,
-          ourPubKey,
-          redeemScript,
-          witnessScript,
-        );
-
-        // updates inline
-        Object.assign(input, prepared);
-      }
-
-      if (!canSign(input)) throw Error(input.prevOutType + ' not supported');
-    }
-
-    // ready to sign
-    let signatureHash: Buffer;
-    if (input.hasWitness) {
-      signatureHash = this.__TX.hashForWitnessV0(
-        vin,
-        input.signScript as Buffer,
-        input.value as number,
+    trySign(
+      getSigningData(
+        this.network,
+        this.__INPUTS,
+        this.__needsOutputs.bind(this),
+        this.__TX,
+        signParams,
+        keyPair,
+        redeemScript,
         hashType,
-      );
-    } else {
-      signatureHash = this.__TX.hashForSignature(
-        vin,
-        input.signScript as Buffer,
-        hashType,
-      );
-    }
-
-    // enforce in order signing of public keys
-    const signed = input.pubkeys!.some((pubKey, i) => {
-      if (!ourPubKey.equals(pubKey!)) return false;
-      if (input.signatures![i]) throw new Error('Signature already exists');
-
-      // TODO: add tests
-      if (ourPubKey.length !== 33 && input.hasWitness) {
-        throw new Error(
-          'BIP143 rejects uncompressed public keys in P2WPKH or P2WSH',
-        );
-      }
-
-      const signature = keyPair.sign(signatureHash, this.__USE_LOW_R);
-      input.signatures![i] = bscript.signature.encode(signature, hashType!);
-      return true;
-    });
-
-    if (!signed) throw new Error('Key pair cannot sign for this input');
+        witnessValue,
+        witnessScript,
+        this.__USE_LOW_R,
+      ),
+    );
   }
 
   private __addInputUnsafe(
@@ -976,3 +951,361 @@ function canSign(input: TxbInput): boolean {
 function signatureHashType(buffer: Buffer): number {
   return buffer.readUInt8(buffer.length - 1);
 }
+
+function checkSignArgs(inputs: TxbInput[], signParams: TxbSignArg): void {
+  if (!PREVOUT_TYPES.has(signParams.prevOutScriptType)) {
+    throw new TypeError(
+      `Unknown prevOutScriptType "${signParams.prevOutScriptType}"`,
+    );
+  }
+  tfMessage(
+    typeforce.Number,
+    signParams.vin,
+    `sign must include vin parameter as Number (input index)`,
+  );
+  tfMessage(
+    types.Signer,
+    signParams.keyPair,
+    `sign must include keyPair parameter as Signer interface`,
+  );
+  tfMessage(
+    typeforce.maybe(typeforce.Number),
+    signParams.hashType,
+    `sign hashType parameter must be a number`,
+  );
+  const prevOutType = (inputs[signParams.vin] || []).prevOutType;
+  const posType = signParams.prevOutScriptType;
+  switch (posType) {
+    case 'p2pkh':
+      if (prevOutType && prevOutType !== 'pubkeyhash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2pkh: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2pk':
+      if (prevOutType && prevOutType !== 'pubkey') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2pk: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2wpkh':
+      if (prevOutType && prevOutType !== 'witnesspubkeyhash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2wpkh: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessValue`,
+      );
+      break;
+    case 'p2ms':
+      if (prevOutType && prevOutType !== 'multisig') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2ms: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2sh-p2wpkh':
+      if (prevOutType && prevOutType !== 'scripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type p2sh-p2wpkh: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.Buffer,
+        signParams.redeemScript,
+        `${posType} requires redeemScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessValue`,
+      );
+      break;
+    case 'p2sh-p2ms':
+    case 'p2sh-p2pk':
+    case 'p2sh-p2pkh':
+      if (prevOutType && prevOutType !== 'scripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type ${posType}: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessScript,
+        `${posType} requires NO witnessScript`,
+      );
+      tfMessage(
+        typeforce.Buffer,
+        signParams.redeemScript,
+        `${posType} requires redeemScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.witnessValue,
+        `${posType} requires NO witnessValue`,
+      );
+      break;
+    case 'p2wsh-p2ms':
+    case 'p2wsh-p2pk':
+    case 'p2wsh-p2pkh':
+      if (prevOutType && prevOutType !== 'witnessscripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type ${posType}: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.Buffer,
+        signParams.witnessScript,
+        `${posType} requires witnessScript`,
+      );
+      tfMessage(
+        typeforce.value(undefined),
+        signParams.redeemScript,
+        `${posType} requires NO redeemScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessValue`,
+      );
+      break;
+    case 'p2sh-p2wsh-p2ms':
+    case 'p2sh-p2wsh-p2pk':
+    case 'p2sh-p2wsh-p2pkh':
+      if (prevOutType && prevOutType !== 'scripthash') {
+        throw new TypeError(
+          `input #${signParams.vin} is not of type ${posType}: ${prevOutType}`,
+        );
+      }
+      tfMessage(
+        typeforce.Buffer,
+        signParams.witnessScript,
+        `${posType} requires witnessScript`,
+      );
+      tfMessage(
+        typeforce.Buffer,
+        signParams.redeemScript,
+        `${posType} requires witnessScript`,
+      );
+      tfMessage(
+        types.Satoshi,
+        signParams.witnessValue,
+        `${posType} requires witnessScript`,
+      );
+      break;
+  }
+}
+
+function trySign({
+  input,
+  ourPubKey,
+  keyPair,
+  signatureHash,
+  hashType,
+  useLowR,
+}: SigningData): void {
+  // enforce in order signing of public keys
+  let signed = false;
+  for (const [i, pubKey] of input.pubkeys!.entries()) {
+    if (!ourPubKey.equals(pubKey!)) continue;
+    if (input.signatures![i]) throw new Error('Signature already exists');
+
+    // TODO: add tests
+    if (ourPubKey.length !== 33 && input.hasWitness) {
+      throw new Error(
+        'BIP143 rejects uncompressed public keys in P2WPKH or P2WSH',
+      );
+    }
+
+    const signature = keyPair.sign(signatureHash, useLowR);
+    input.signatures![i] = bscript.signature.encode(signature, hashType);
+    signed = true;
+  }
+
+  if (!signed) throw new Error('Key pair cannot sign for this input');
+}
+
+interface SigningData {
+  input: TxbInput;
+  ourPubKey: Buffer;
+  keyPair: Signer;
+  signatureHash: Buffer;
+  hashType: number;
+  useLowR: boolean;
+}
+
+type HashTypeCheck = (hashType: number) => boolean;
+
+function getSigningData(
+  network: Network,
+  inputs: TxbInput[],
+  needsOutputs: HashTypeCheck,
+  tx: Transaction,
+  signParams: number | TxbSignArg,
+  keyPair?: Signer,
+  redeemScript?: Buffer,
+  hashType?: number,
+  witnessValue?: number,
+  witnessScript?: Buffer,
+  useLowR?: boolean,
+): SigningData {
+  let vin: number;
+  if (typeof signParams === 'number') {
+    console.warn(
+      'DEPRECATED: TransactionBuilder sign method arguments ' +
+        'will change in v6, please use the TxbSignArg interface',
+    );
+    vin = signParams;
+  } else if (typeof signParams === 'object') {
+    checkSignArgs(inputs, signParams);
+    ({
+      vin,
+      keyPair,
+      redeemScript,
+      hashType,
+      witnessValue,
+      witnessScript,
+    } = signParams);
+  } else {
+    throw new TypeError(
+      'TransactionBuilder sign first arg must be TxbSignArg or number',
+    );
+  }
+  if (keyPair === undefined) {
+    throw new Error('sign requires keypair');
+  }
+  // TODO: remove keyPair.network matching in 4.0.0
+  if (keyPair.network && keyPair.network !== network)
+    throw new TypeError('Inconsistent network');
+  if (!inputs[vin]) throw new Error('No input at index: ' + vin);
+
+  hashType = hashType || Transaction.SIGHASH_ALL;
+  if (needsOutputs(hashType)) throw new Error('Transaction needs outputs');
+
+  const input = inputs[vin];
+
+  // if redeemScript was previously provided, enforce consistency
+  if (
+    input.redeemScript !== undefined &&
+    redeemScript &&
+    !input.redeemScript.equals(redeemScript)
+  ) {
+    throw new Error('Inconsistent redeemScript');
+  }
+
+  const ourPubKey =
+    keyPair.publicKey || (keyPair.getPublicKey && keyPair.getPublicKey());
+  if (!canSign(input)) {
+    if (witnessValue !== undefined) {
+      if (input.value !== undefined && input.value !== witnessValue)
+        throw new Error('Input did not match witnessValue');
+      typeforce(types.Satoshi, witnessValue);
+      input.value = witnessValue;
+    }
+
+    if (!canSign(input)) {
+      const prepared = prepareInput(
+        input,
+        ourPubKey,
+        redeemScript,
+        witnessScript,
+      );
+
+      // updates inline
+      Object.assign(input, prepared);
+    }
+
+    if (!canSign(input)) throw Error(input.prevOutType + ' not supported');
+  }
+
+  // ready to sign
+  let signatureHash: Buffer;
+  if (input.hasWitness) {
+    signatureHash = tx.hashForWitnessV0(
+      vin,
+      input.signScript as Buffer,
+      input.value as number,
+      hashType,
+    );
+  } else {
+    signatureHash = tx.hashForSignature(
+      vin,
+      input.signScript as Buffer,
+      hashType,
+    );
+  }
+
+  return {
+    input,
+    ourPubKey,
+    keyPair,
+    signatureHash,
+    hashType,
+    useLowR: !!useLowR,
+  };
+}
diff --git a/ts_src/types.ts b/ts_src/types.ts
index 06c247d..2e41267 100644
--- a/ts_src/types.ts
+++ b/ts_src/types.ts
@@ -12,6 +12,14 @@ BIP32Path.toJSON = (): string => {
   return 'BIP32 derivation path';
 };
 
+export function Signer(obj: any): boolean {
+  return (
+    (typeforce.Buffer(obj.publicKey) ||
+      typeof obj.getPublicKey === 'function') &&
+    typeof obj.sign === 'function'
+  );
+}
+
 const SATOSHI_MAX: number = 21 * 1e14;
 export function Satoshi(value: number): boolean {
   return typeforce.UInt53(value) && value <= SATOSHI_MAX;
diff --git a/types/ecpair.d.ts b/types/ecpair.d.ts
index 5f301b2..8b7d193 100644
--- a/types/ecpair.d.ts
+++ b/types/ecpair.d.ts
@@ -5,15 +5,24 @@ interface ECPairOptions {
     network?: Network;
     rng?(arg0: number): Buffer;
 }
-export interface ECPairInterface {
+export interface Signer {
+    publicKey: Buffer;
+    network?: Network;
+    sign(hash: Buffer, lowR?: boolean): Buffer;
+    getPublicKey?(): Buffer;
+}
+export interface SignerAsync {
+    publicKey: Buffer;
+    network?: Network;
+    sign(hash: Buffer, lowR?: boolean): Promise<Buffer>;
+    getPublicKey?(): Buffer;
+}
+export interface ECPairInterface extends Signer {
     compressed: boolean;
     network: Network;
-    publicKey: Buffer;
     privateKey?: Buffer;
     toWIF(): string;
-    sign(hash: Buffer, lowR?: boolean): Buffer;
     verify(hash: Buffer, signature: Buffer): boolean;
-    getPublicKey?(): Buffer;
 }
 declare class ECPair implements ECPairInterface {
     private __D?;
diff --git a/types/index.d.ts b/types/index.d.ts
index 28046df..93d72e4 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -11,7 +11,7 @@ export { OPS as opcodes } from './script';
 export { Transaction } from './transaction';
 export { TransactionBuilder } from './transaction_builder';
 export { BIP32Interface } from 'bip32';
-export { ECPairInterface } from './ecpair';
+export { ECPairInterface, Signer, SignerAsync } from './ecpair';
 export { Network } from './networks';
 export { Payment, PaymentOpts, Stack, StackElement } from './payments';
 export { OpCode } from './script';
diff --git a/types/transaction_builder.d.ts b/types/transaction_builder.d.ts
index f993807..2799464 100644
--- a/types/transaction_builder.d.ts
+++ b/types/transaction_builder.d.ts
@@ -1,7 +1,16 @@
 /// <reference types="node" />
-import { ECPairInterface } from './ecpair';
+import { Signer } from './ecpair';
 import { Network } from './networks';
 import { Transaction } from './transaction';
+interface TxbSignArg {
+    prevOutScriptType: string;
+    vin: number;
+    keyPair: Signer;
+    redeemScript?: Buffer;
+    hashType?: number;
+    witnessValue?: number;
+    witnessScript?: Buffer;
+}
 export declare class TransactionBuilder {
     network: Network;
     maximumFeeRate: number;
@@ -18,7 +27,7 @@ export declare class TransactionBuilder {
     addOutput(scriptPubKey: string | Buffer, value: number): number;
     build(): Transaction;
     buildIncomplete(): Transaction;
-    sign(vin: number, keyPair: ECPairInterface, redeemScript?: Buffer, hashType?: number, witnessValue?: number, witnessScript?: Buffer): void;
+    sign(signParams: number | TxbSignArg, keyPair?: Signer, redeemScript?: Buffer, hashType?: number, witnessValue?: number, witnessScript?: Buffer): void;
     private __addInputUnsafe;
     private __build;
     private __canModifyInputs;
@@ -26,3 +35,4 @@ export declare class TransactionBuilder {
     private __canModifyOutputs;
     private __overMaximumFees;
 }
+export {};
diff --git a/types/types.d.ts b/types/types.d.ts
index 242bab8..e7c588d 100644
--- a/types/types.d.ts
+++ b/types/types.d.ts
@@ -3,6 +3,7 @@ export declare function BIP32Path(value: string): boolean;
 export declare namespace BIP32Path {
     var toJSON: () => string;
 }
+export declare function Signer(obj: any): boolean;
 export declare function Satoshi(value: number): boolean;
 export declare const ECPoint: any;
 export declare const Network: any;