private static void settleCLTVPaymentChannel(String txHash, String output, Coin feePerVkb, boolean allowUnconfirmed) {
        try {
            OutputSpec outputSpec;
            Coin value;
            try {
                outputSpec = new OutputSpec(output);
                value = outputSpec.value;
            } catch (AddressFormatException.WrongNetwork e) {
                System.err.println("Malformed output specification, address is for a different network.");
                return;
            } catch (AddressFormatException e) {
                System.err.println("Malformed output specification, could not parse as address.");
                return;
            } catch (NumberFormatException e) {
                System.err.println("Malformed output specification, could not parse as value.");
                return;
            } catch (IllegalArgumentException e) {
                System.err.println(e.getMessage());
                return;
            }

            SendRequest req = outputSpec.isAddress() ?
                    SendRequest.to(outputSpec.addr, value) :
                    SendRequest.to(params, outputSpec.key, value);
            if (feePerVkb != null)
                req.setFeePerVkb(feePerVkb);

            Transaction lockTimeVerify = wallet.getTransaction(Sha256Hash.wrap(txHash));
            if (lockTimeVerify == null) {
                System.err.println("Couldn't find transaction with given hash");
                return;
            }
            TransactionOutput lockTimeVerifyOutput = null;
            for (TransactionOutput out : lockTimeVerify.getOutputs()) {
                if (ScriptPattern.isSentToCltvPaymentChannel(out.getScriptPubKey())) {
                    lockTimeVerifyOutput = out;
                }
            }
            if (lockTimeVerifyOutput == null) {
                System.err.println("TX to spend wasn't sent to LockTimeVerify");
                return;
            }

            if (!value.equals(lockTimeVerifyOutput.getValue())) {
                System.err.println("You must spend all the money in the input transaction");
            }

            if (allowUnconfirmed) {
                wallet.allowSpendingUnconfirmedTransactions();
            }
            if (password != null) {
                req.aesKey = passwordToKey(true);
                if (req.aesKey == null)
                    return;  // Error message already printed.
            }

            ECKey key1 = wallet.findKeyFromPubKey(
                    ScriptPattern.extractSenderPubKeyFromCltvPaymentChannel(lockTimeVerifyOutput.getScriptPubKey()));
            ECKey key2 = wallet.findKeyFromPubKey(
                    ScriptPattern.extractRecipientPubKeyFromCltvPaymentChannel(lockTimeVerifyOutput.getScriptPubKey()));
            if (key1 == null || key2 == null) {
                System.err.println("Don't own private keys for both pubkeys");
                return;
            }

            TransactionInput input = new TransactionInput(
                    params, req.tx, new byte[] {}, lockTimeVerifyOutput.getOutPointFor());
            req.tx.addInput(input);
            TransactionSignature sig1 =
                    req.tx.calculateSignature(0, key1, lockTimeVerifyOutput.getScriptPubKey(), Transaction.SigHash.SINGLE, false);
            TransactionSignature sig2 =
                    req.tx.calculateSignature(0, key2, lockTimeVerifyOutput.getScriptPubKey(), Transaction.SigHash.SINGLE, false);
            input.setScriptSig(ScriptBuilder.createCLTVPaymentChannelInput(sig1, sig2));

            System.out.println(req.tx.getTxId());
            if (options.has("offline")) {
                wallet.commitTx(req.tx);
                return;
            }

            setup();
            peerGroup.start();
            // Wait for peers to connect, the tx to be sent to one of them and for it to be propagated across the
            // network. Once propagation is complete and we heard the transaction back from all our peers, it will
            // be committed to the wallet.
            peerGroup.broadcastTransaction(req.tx).future().get();
            // Hack for regtest/single peer mode, as we're about to shut down and won't get an ACK from the remote end.
            List<Peer> peerList = peerGroup.getConnectedPeers();
            if (peerList.size() == 1)
                peerList.get(0).ping().get();
        } catch (BlockStoreException e) {
            throw new RuntimeException(e);
        } catch (KeyCrypterException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
private static void settleCLTVPaymentChannel ( String txHash , String output , Coin feePerVkb , boolean allowUnconfirmed ) { try { OutputSpec outputSpec ; Coin value ; try { outputSpec = new OutputSpec ( output ) ; value = outputSpec . value ; } catch ( AddressFormatException . WrongNetwork e ) { System . err . println ( "Malformed output specification, address is for a different network." ) ; return ; } catch ( AddressFormatException e ) { System . err . println ( "Malformed output specification, could not parse as address." ) ; return ; } catch ( NumberFormatException e ) { System . err . println ( "Malformed output specification, could not parse as value." ) ; return ; } catch ( IllegalArgumentException e ) { System . err . println ( e . getMessage ( ) ) ; return ; } SendRequest req = outputSpec . isAddress ( ) ? SendRequest . to ( outputSpec . addr , value ) : SendRequest . to ( params , outputSpec . key , value ) ; if ( feePerVkb != null ) req . setFeePerVkb ( feePerVkb ) ; Transaction lockTimeVerify = wallet . getTransaction ( Sha256Hash . wrap ( txHash ) ) ; if ( lockTimeVerify == null ) { System . err . println ( "Couldn't find transaction with given hash" ) ; return ; } TransactionOutput lockTimeVerifyOutput = null ; for ( TransactionOutput out : lockTimeVerify . getOutputs ( ) ) { if ( ScriptPattern . isSentToCltvPaymentChannel ( out . getScriptPubKey ( ) ) ) { lockTimeVerifyOutput = out ; } } if ( lockTimeVerifyOutput == null ) { System . err . println ( "TX to spend wasn't sent to LockTimeVerify" ) ; return ; } if ( ! value . equals ( lockTimeVerifyOutput . getValue ( ) ) ) { System . err . println ( "You must spend all the money in the input transaction" ) ; } if ( allowUnconfirmed ) { wallet . allowSpendingUnconfirmedTransactions ( ) ; } if ( password != null ) { req . aesKey = passwordToKey ( true ) ; if ( req . aesKey == null ) return ; } ECKey key1 = wallet . findKeyFromPubKey ( ScriptPattern . extractSenderPubKeyFromCltvPaymentChannel ( lockTimeVerifyOutput . getScriptPubKey ( ) ) ) ; ECKey key2 = wallet . findKeyFromPubKey ( ScriptPattern . extractRecipientPubKeyFromCltvPaymentChannel ( lockTimeVerifyOutput . getScriptPubKey ( ) ) ) ; if ( key1 == null || key2 == null ) { System . err . println ( "Don't own private keys for both pubkeys" ) ; return ; } TransactionInput input = new TransactionInput ( params , req . tx , new byte [ ] { } , lockTimeVerifyOutput . getOutPointFor ( ) ) ; req . tx . addInput ( input ) ; TransactionSignature sig1 = req . tx . calculateSignature ( 0 , key1 , lockTimeVerifyOutput . getScriptPubKey ( ) , Transaction . SigHash . SINGLE , false ) ; TransactionSignature sig2 = req . tx . calculateSignature ( 0 , key2 , lockTimeVerifyOutput . getScriptPubKey ( ) , Transaction . SigHash . SINGLE , false ) ; input . setScriptSig ( ScriptBuilder . createCLTVPaymentChannelInput ( sig1 , sig2 ) ) ; System . out . println ( req . tx . getTxId ( ) ) ; if ( options . has ( "offline" ) ) { wallet . commitTx ( req . tx ) ; return ; } setup ( ) ; peerGroup . start ( ) ; peerGroup . broadcastTransaction ( req . tx ) . future ( ) . get ( ) ; List < Peer > peerList = peerGroup . getConnectedPeers ( ) ; if ( peerList . size ( ) == 1 ) peerList . get ( 0 ) . ping ( ) . get ( ) ; } catch ( BlockStoreException e ) { throw new RuntimeException ( e ) ; } catch ( KeyCrypterException e ) { throw new RuntimeException ( e ) ; } catch ( InterruptedException e ) { throw new RuntimeException ( e ) ; } catch ( ExecutionException e ) { throw new RuntimeException ( e ) ; } }
Settles a CLTV payment channel transaction given that we own both private keys (ie. for testing).