protected function signTransaction(TransactionInterface $tx, array $signInfo) {
        $signer = new Signer($tx, Bitcoin::getEcAdapter());

        $sigHash = SigHash::ALL;
        if ($this->network === "bitcoincash") {
            $sigHash |= SigHash::BITCOINCASH;
            $signer->redeemBitcoinCash(true);
        }

        assert(Util::all(function ($signInfo) {
            return $signInfo instanceof SignInfo;
        }, $signInfo), '$signInfo should be SignInfo[]');

        foreach ($signInfo as $idx => $info) {
            if ($info->mode === SignInfo::MODE_SIGN) {
                $path = BIP32Path::path($info->path)->privatePath();
                $redeemScript = $info->redeemScript;
                $output = $info->output;

                $key = $this->primaryPrivateKey->buildKey($path)->key()->getPrivateKey();
                $backupKey = $this->backupPrivateKey->buildKey($path->unhardenedPath())->key()->getPrivateKey();

                $signData = (new SignData())
                    ->p2sh($redeemScript);

                if ($info->witnessScript) {
                    $signData->p2wsh($info->witnessScript);
                }

                $input = $signer->input($idx, $output, $signData);

                $input->sign($key, $sigHash);
                $input->sign($backupKey, $sigHash);
            }
        }

        return $signer->get();
    }