diff --git a/Eclair-ChannelFundingPlugin/.classpath b/Eclair-ChannelFundingPlugin/.classpath
new file mode 100644
index 0000000..a8067c5
--- /dev/null
+++ b/Eclair-ChannelFundingPlugin/.classpath
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Eclair-ChannelFundingPlugin/pom.xml b/Eclair-ChannelFundingPlugin/pom.xml
new file mode 100644
index 0000000..de278d4
--- /dev/null
+++ b/Eclair-ChannelFundingPlugin/pom.xml
@@ -0,0 +1,179 @@
+
+
+ 4.0.0
+
+ fr.acinq.eclair.plugin
+ ChannelFundingPlugin
+ 0.0.3
+ jar
+
+
+ UTF-8
+ 2.13.10
+ 2.13
+ 0.9.0
+ 2.6.20
+ 10.2.7
+ 3.8.5
+ 0.28
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.5
+
+
+ 1.8
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.2
+
+
+
+ false
+ fr.acinq.ChannelInterceptor.ChannelFundingPlugin
+
+
+
+
+
+
+
+
+ maven-assembly-plugin
+ 2.2.1
+
+
+ jar-with-dependencies
+
+
+
+ fr.acinq.ChannelInterceptor.ChannelFundingPlugin
+
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
+ fr.acinq
+ bitcoin-lib_${scala.version.short}
+ ${bitcoinlib.version}
+ provided
+
+
+ org.scala-lang
+ scala-library
+ ${scala.version}
+ provided
+
+
+
+ fr.acinq.eclair
+ eclair-core_2.13
+ ${eclair.version}
+ provided
+
+
+ fr.acinq.eclair
+ eclair-node_2.13
+ ${eclair.version}
+ provided
+
+
+ org.clapper
+ grizzled-slf4j_2.13
+ 1.3.4
+ provided
+
+
+ com.typesafe.akka
+ akka-http_${scala.version.short}
+ ${akka.http.version}
+
+
+ com.typesafe.akka
+ akka-stream_${scala.version.short}
+ ${akka.version}
+ provided
+
+
+ com.typesafe.akka
+ akka-actor-typed_${scala.version.short}
+ ${akka.version}
+ provided
+
+
+ org.json4s
+ json4s-native_${scala.version.short}
+ 3.6.10
+ provided
+
+
+ com.softwaremill.sttp.client3
+ json4s_${scala.version.short}
+ ${sttp.version}
+ provided
+
+
+ com.softwaremill.sttp
+ okhttp-backend_${scala.version.short}
+ 1.7.2
+ provided
+
+
+ org.bouncycastle
+ bcprov-jdk18on
+ 1.71
+ provided
+
+
+ org.slf4j
+ slf4j-api
+ 1.7.36
+ provided
+
+
+ org.json
+ json
+ 20160810
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.39.3.0
+
+
+ org.postgresql
+ postgresql
+ 42.3.3
+
+
+ com.google.code.gson
+ gson
+ 2.10.1
+
+
+
+
+
\ No newline at end of file
diff --git a/Eclair-ChannelFundingPlugin/readme.md b/Eclair-ChannelFundingPlugin/readme.md
new file mode 100644
index 0000000..00c4814
--- /dev/null
+++ b/Eclair-ChannelFundingPlugin/readme.md
@@ -0,0 +1,7 @@
+#ChannelFundingPlugin
+
+This is a plugin for eclair lightning node.
+It lets you create rules for new incoming channels.
+
+There is a sample config here:
+
diff --git a/Eclair-ChannelFundingPlugin/src/main/java/fr/acinq/ChannelInterceptor/ChannelFundingPlugin.java b/Eclair-ChannelFundingPlugin/src/main/java/fr/acinq/ChannelInterceptor/ChannelFundingPlugin.java
new file mode 100644
index 0000000..7ca77b0
--- /dev/null
+++ b/Eclair-ChannelFundingPlugin/src/main/java/fr/acinq/ChannelInterceptor/ChannelFundingPlugin.java
@@ -0,0 +1,117 @@
+package fr.acinq.ChannelInterceptor;
+
+
+import akka.actor.ActorSystem;
+import akka.actor.typed.ActorRef;
+import akka.actor.typed.Behavior;
+import akka.actor.typed.javadsl.Adapter;
+import akka.actor.typed.SupervisorStrategy;
+import akka.actor.typed.javadsl.Behaviors;
+import fr.acinq.eclair.InterceptOpenChannelCommand;
+import fr.acinq.eclair.InterceptOpenChannelPlugin;
+import fr.acinq.eclair.Kit;
+import fr.acinq.eclair.NodeParams;
+import fr.acinq.eclair.Plugin;
+import fr.acinq.eclair.PluginParams;
+import fr.acinq.eclair.Setup;
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+
+/**
+ * Intercept OpenChannel messages received by the node and respond by continuing the process
+ * of accepting the request, potentially with different local parameters, or failing the request.
+ */
+public class ChannelFundingPlugin implements Plugin {
+ final static Logger logger = LoggerFactory.getLogger(ChannelFundingPlugin.class);
+
+ private OpenChannelInterceptorKit pluginKit;
+ private File configFile;
+
+ @Override
+ public PluginParams params() {
+ return new InterceptOpenChannelPlugin() {
+ @Override
+ public String name() {
+ return "ChannelFundingPlugin";
+ }
+
+ @Override
+ public ActorRef openChannelInterceptor() {
+ return pluginKit.openChannelInterceptor();
+ }
+ };
+ }
+
+ @Override
+ public void onSetup(Setup setup) {
+ File datadir = new File(setup.datadir().toPath().toAbsolutePath().toString());
+ File resourcesDir = new File(datadir,"/plugin-resources/ChannelFunding/");
+ configFile = new File(resourcesDir,"ChannelFunding.conf");
+ logger.info("Using config file: "+configFile.getAbsolutePath());
+
+ //we load the config once at startup to check if at least hte default accept rule is set
+ try {
+ Config PluginConf = ConfigFactory.parseFile(configFile).resolve();
+
+ @SuppressWarnings("unused")
+ boolean accept = PluginConf.getBoolean("open-channel-interceptor.default.accept");
+ @SuppressWarnings("unused")
+ long min_channel_size = PluginConf.getLong("open-channel-interceptor.default.min_channel_size");
+ @SuppressWarnings("unused")
+ long max_channel_size = PluginConf.getLong("open-channel-interceptor.default.max_channel_size");
+ @SuppressWarnings("unused")
+ int min_active_channels = PluginConf.getInt("open-channel-interceptor.default.min_active_channels");
+ } catch (Throwable e)
+ {
+ logger.error("Can not read default accept rules from config file");
+ logger.error(""+e);
+ }
+
+ logger.info("ChannelFundingPlugin finished startup");
+ }
+
+ @Override
+ public void onKit(Kit kit) {
+
+ ActorSystem actorSystem = kit.system();
+ Behavior MyBehaviour = Behaviors.supervise(OpenChannelInterceptor.apply(configFile.getAbsolutePath(), Adapter.toTyped(kit.router())))
+ .onFailure(SupervisorStrategy.restart());
+
+ akka.actor.typed.ActorRef openChannelInterceptor = Adapter.spawnAnonymous(actorSystem, MyBehaviour);
+
+
+ pluginKit = new OpenChannelInterceptorKit(kit.nodeParams(), kit.system(), openChannelInterceptor);
+
+ logger.info("ChannelFundingPlugin subscribed to events");
+ }
+
+}
+
+class OpenChannelInterceptorKit {
+ private final NodeParams nodeParams;
+ private final ActorSystem system;
+ private final ActorRef openChannelInterceptor;
+
+ public OpenChannelInterceptorKit(NodeParams nodeParams, ActorSystem system, ActorRef openChannelInterceptor) {
+ this.nodeParams = nodeParams;
+ this.system = system;
+ this.openChannelInterceptor = openChannelInterceptor;
+ }
+
+ public NodeParams nodeParams() {
+ return nodeParams;
+ }
+
+ public ActorSystem system() {
+ return system;
+ }
+
+ public ActorRef openChannelInterceptor() {
+ return openChannelInterceptor;
+ }
+}
diff --git a/Eclair-ChannelFundingPlugin/src/main/java/fr/acinq/ChannelInterceptor/OpenChannelInterceptor.java b/Eclair-ChannelFundingPlugin/src/main/java/fr/acinq/ChannelInterceptor/OpenChannelInterceptor.java
new file mode 100644
index 0000000..313fa20
--- /dev/null
+++ b/Eclair-ChannelFundingPlugin/src/main/java/fr/acinq/ChannelInterceptor/OpenChannelInterceptor.java
@@ -0,0 +1,176 @@
+package fr.acinq.ChannelInterceptor;
+
+import akka.actor.typed.Behavior;
+
+import java.io.File;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+
+import akka.actor.typed.ActorRef;
+import akka.actor.typed.javadsl.ActorContext;
+import akka.actor.typed.javadsl.Behaviors;
+import fr.acinq.eclair.router.Router;
+import fr.acinq.eclair.router.Router.GetNode;
+import fr.acinq.eclair.router.Router.PublicNode;
+import fr.acinq.eclair.router.Router.UnknownNode;
+import fr.acinq.eclair.wire.protocol.Error;
+import fr.acinq.eclair.AcceptOpenChannel;
+import fr.acinq.eclair.InterceptOpenChannelCommand;
+import fr.acinq.eclair.InterceptOpenChannelReceived;
+import fr.acinq.eclair.RejectOpenChannel;
+
+/**
+ * Intercept OpenChannel and OpenDualFundedChannel messages received by the node. Respond to the peer
+ * that received the request with AcceptOpenChannel to continue the open channel process,
+ * optionally with modified default parameters, or fail the request by responding to the initiator
+ * with RejectOpenChannel and an Error message.
+ *
+ * This example plugin decides how much funds (if any) the non-initiator should put into a dual-funded channel. It also
+ * demonstrates how to reject requests from nodes with less than a minimum amount of total capacity or too few public
+ * channels.
+ *
+ * Note: only one open channel request can be processed at a time.
+ */
+public class OpenChannelInterceptor {
+ final static Logger logger = LoggerFactory.getLogger(OpenChannelInterceptor.class);
+
+
+
+ private static class WrappedGetNodeResponse implements InterceptOpenChannelCommand {
+ private final InterceptOpenChannelReceived interceptOpenChannelReceived;
+ private final Router.GetNodeResponse response;
+
+ public WrappedGetNodeResponse(InterceptOpenChannelReceived interceptOpenChannelReceived, Router.GetNodeResponse response) {
+ this.interceptOpenChannelReceived = interceptOpenChannelReceived;
+ this.response = response;
+ }
+
+ public InterceptOpenChannelReceived getInterceptOpenChannelReceived() {
+ return interceptOpenChannelReceived;
+ }
+
+ public Router.GetNodeResponse getResponse() {
+ return response;
+ }
+ }
+
+ public static Behavior apply(String configPath, ActorRef