Commit d10772ec authored by Daniel Connolly's avatar Daniel Connolly

remove examples using payment channels

parent 821bd00d
* Copyright 2013 Google Inc.
* Copyright 2014 Andreas Schildbach
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
package org.bitcoinj.examples;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.VerificationException;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.RegTestParams;
import org.bitcoinj.protocols.channels.*;
import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.wallet.WalletExtension;
import org.slf4j.LoggerFactory;
import java.util.List;
* Simple server that listens on port 4242 for incoming payment channels.
public class ExamplePaymentChannelServer implements PaymentChannelServerListener.HandlerFactory {
private static final org.slf4j.Logger log = LoggerFactory.getLogger(ExamplePaymentChannelServer.class);
private WalletAppKit appKit;
public static void main(String[] args) throws Exception {
OptionParser parser = new OptionParser();
OptionSpec<NetworkEnum> net = parser.accepts("net", "The network to run the examples on").withRequiredArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.TEST);
parser.accepts("help", "Displays program options");
OptionSet opts = parser.parse(args);
if (opts.has("help") || !opts.has(net)) {
System.err.println("usage: ExamplePaymentChannelServer --net=MAIN/TEST/REGTEST");
NetworkParameters params = net.value(opts).get();
new ExamplePaymentChannelServer().run(params);
public void run(NetworkParameters params) throws Exception {
// Bring up all the objects we need, create/load a wallet, sync the chain, etc. We override WalletAppKit so we
// can customize it by adding the extension objects - we have to do this before the wallet file is loaded so
// the plugin that knows how to parse all the additional data is present during the load.
appKit = new WalletAppKit(params, new File("."), "payment_channel_example_server") {
protected List<WalletExtension> provideWalletExtensions() {
// The StoredPaymentChannelClientStates object is responsible for, amongst other things, broadcasting
// the refund transaction if its lock time has expired. It also persists channels so we can resume them
// after a restart.
return ImmutableList.<WalletExtension>of(new StoredPaymentChannelServerStates(null));
// Broadcasting can take a bit of time so we up the timeout for "real" networks
final int timeoutSeconds = params.getId().equals(NetworkParameters.ID_REGTEST) ? 15 : 150;
if (params == RegTestParams.get()) {
// We provide a peer group, a wallet, a timeout in seconds, the amount we require to start a channel and
// an implementation of HandlerFactory, which we just implement ourselves.
new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), timeoutSeconds, Coin.valueOf(100000), this).bindAndStart(4242);
public ServerConnectionEventHandler onNewConnection(final SocketAddress clientAddress) {
// Each connection needs a handler which is informed when that payment channel gets adjusted. Here we just log
// things. In a real app this object would be connected to some business logic.
return new ServerConnectionEventHandler() {
public void channelOpen(Sha256Hash channelId) {"Channel open for {}: {}.", clientAddress, channelId);
// Try to get the state object from the stored state set in our wallet
PaymentChannelServerState state = null;
try {
StoredPaymentChannelServerStates storedStates = (StoredPaymentChannelServerStates)
state = storedStates.getChannel(channelId).getOrCreateState(appKit.wallet(), appKit.peerGroup());
} catch (VerificationException e) {
// This indicates corrupted data, and since the channel was just opened, cannot happen
throw new RuntimeException(e);
}" with a maximum value of {}, expiring at UNIX timestamp {}.",
// The channel's maximum value is the value of the multisig contract which locks in some
// amount of money to the channel
// The channel expires at some offset from when the client's refund transaction becomes
// spendable.
state.getExpiryTime() + StoredPaymentChannelServerStates.CHANNEL_EXPIRE_OFFSET);
public ListenableFuture<ByteString> paymentIncrease(Coin by, Coin to, ByteString info) {"Client {} paid increased payment by {} for a total of " + to.toString(), clientAddress, by);
return null;
public void channelClosed(PaymentChannelCloseException.CloseReason reason) {"Client {} closed channel for reason {}", clientAddress, reason);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment