@Override
 public byte[] serializeWalletExtension() {
   lock.lock();
   try {
     ClientState.StoredClientPaymentChannels.Builder builder =
         ClientState.StoredClientPaymentChannels.newBuilder();
     for (StoredClientChannel channel : mapChannels.values()) {
       // First a few asserts to make sure things won't break
       checkState(
           channel.valueToMe.signum() >= 0
               && channel.valueToMe.compareTo(NetworkParameters.MAX_MONEY) < 0);
       checkState(
           channel.refundFees.signum() >= 0
               && channel.refundFees.compareTo(NetworkParameters.MAX_MONEY) < 0);
       checkNotNull(channel.myKey.getPubKey());
       checkState(channel.refund.getConfidence().getSource() == TransactionConfidence.Source.SELF);
       final ClientState.StoredClientPaymentChannel.Builder value =
           ClientState.StoredClientPaymentChannel.newBuilder()
               .setId(ByteString.copyFrom(channel.id.getBytes()))
               .setContractTransaction(ByteString.copyFrom(channel.contract.bitcoinSerialize()))
               .setRefundTransaction(ByteString.copyFrom(channel.refund.bitcoinSerialize()))
               .setMyKey(
                   ByteString.copyFrom(new byte[0])) // Not  used, but protobuf message requires
               .setMyPublicKey(ByteString.copyFrom(channel.myKey.getPubKey()))
               .setValueToMe(channel.valueToMe.value)
               .setRefundFees(channel.refundFees.value);
       if (channel.close != null)
         value.setCloseTransactionHash(ByteString.copyFrom(channel.close.getHash().getBytes()));
       builder.addChannels(value);
     }
     return builder.build().toByteArray();
   } finally {
     lock.unlock();
   }
 }
 @Override
 public void deserializeWalletExtension(Wallet containingWallet, byte[] data) throws Exception {
   lock.lock();
   try {
     checkState(this.containingWallet == null || this.containingWallet == containingWallet);
     this.containingWallet = containingWallet;
     NetworkParameters params = containingWallet.getParams();
     ClientState.StoredClientPaymentChannels states =
         ClientState.StoredClientPaymentChannels.parseFrom(data);
     for (ClientState.StoredClientPaymentChannel storedState : states.getChannelsList()) {
       Transaction refundTransaction =
           params
               .getDefaultSerializer()
               .makeTransaction(storedState.getRefundTransaction().toByteArray());
       refundTransaction.getConfidence().setSource(TransactionConfidence.Source.SELF);
       ECKey myKey =
           (storedState.getMyKey().isEmpty())
               ? containingWallet.findKeyFromPubKey(storedState.getMyPublicKey().toByteArray())
               : ECKey.fromPrivate(storedState.getMyKey().toByteArray());
       StoredClientChannel channel =
           new StoredClientChannel(
               Sha256Hash.wrap(storedState.getId().toByteArray()),
               params
                   .getDefaultSerializer()
                   .makeTransaction(storedState.getContractTransaction().toByteArray()),
               refundTransaction,
               myKey,
               Coin.valueOf(storedState.getValueToMe()),
               Coin.valueOf(storedState.getRefundFees()),
               false);
       if (storedState.hasCloseTransactionHash()) {
         Sha256Hash closeTxHash =
             Sha256Hash.wrap(storedState.getCloseTransactionHash().toByteArray());
         channel.close = containingWallet.getTransaction(closeTxHash);
       }
       putChannel(channel, false);
     }
   } finally {
     lock.unlock();
   }
 }