@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 =
           new Transaction(params, storedState.getRefundTransaction().toByteArray());
       refundTransaction.getConfidence().setSource(TransactionConfidence.Source.SELF);
       StoredClientChannel channel =
           new StoredClientChannel(
               new Sha256Hash(storedState.getId().toByteArray()),
               new Transaction(params, storedState.getContractTransaction().toByteArray()),
               refundTransaction,
               new ECKey(new BigInteger(1, storedState.getMyKey().toByteArray()), null, true),
               BigInteger.valueOf(storedState.getValueToMe()),
               BigInteger.valueOf(storedState.getRefundFees()),
               false);
       if (storedState.hasCloseTransactionHash())
         channel.close =
             containingWallet.getTransaction(new Sha256Hash(storedState.toByteArray()));
       putChannel(channel, false);
     }
   } finally {
     lock.unlock();
   }
 }
 @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.getPrivKeyBytes());
       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(channel.myKey.getPrivKeyBytes()))
               .setValueToMe(channel.valueToMe.longValue())
               .setRefundFees(channel.refundFees.longValue());
       if (channel.close != null)
         value.setCloseTransactionHash(ByteString.copyFrom(channel.close.getHash().getBytes()));
       builder.addChannels(value);
     }
     return builder.build().toByteArray();
   } finally {
     lock.unlock();
   }
 }