github.com/decred/dcrlnd@v0.7.6/docs/grpc/java.md (about)

     1  
     2  # How to write a Java gRPC client for the Lightning Network Daemon
     3  
     4  This section enumerates what you need to do to write a client that communicates
     5  with lnd in Java. We'll be using Maven as our build tool.
     6  
     7  ### Prerequisites
     8   - Maven
     9   - running lnd
    10   - running btcd
    11  
    12  ### Setup and Installation
    13  #### Project Structure
    14  ```
    15  .
    16  ├── pom.xml
    17  └── src
    18      ├── main
    19         ├── java
    20         │   └── Main.java
    21         ├── proto
    22            ├── google
    23            │   └── api
    24            │       ├── annotations.proto
    25            │       └── http.proto
    26            └── lnrpc
    27                └── lightning.proto
    28  
    29  ```
    30  Note the ***proto*** folder, where all the proto files are kept.
    31  
    32   - [lightning.proto](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/lightning.proto)
    33   - [annotations.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/third_party/googleapis/google/api/annotations.proto)
    34   - [http.proto](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/third_party/googleapis/google/api/http.proto)
    35  
    36  #### pom.xml
    37  ```
    38  <properties>
    39      <grpc.version>1.8.0</grpc.version>
    40  </properties>    
    41  ```
    42  The following dependencies are required.
    43  ```
    44  <dependencies>
    45      <dependency>
    46          <groupId>io.grpc</groupId>
    47          <artifactId>grpc-netty</artifactId>
    48          <version>${grpc.version}</version>
    49      </dependency>
    50      <dependency>
    51          <groupId>io.grpc</groupId>
    52          <artifactId>grpc-protobuf</artifactId>
    53          <version>${grpc.version}</version>
    54      </dependency>
    55      <dependency>
    56          <groupId>io.grpc</groupId>
    57          <artifactId>grpc-stub</artifactId>
    58          <version>${grpc.version}</version>
    59      </dependency>
    60      <dependency>
    61          <groupId>io.netty</groupId>
    62          <artifactId>netty-tcnative-boringssl-static</artifactId>
    63          <version>2.0.7.Final</version>
    64      </dependency>
    65      <dependency>
    66          <groupId>commons-codec</groupId>
    67          <artifactId>commons-codec</artifactId>
    68          <version>1.11</version>
    69      </dependency>
    70  </dependencies>
    71  ```
    72  In the build section,  we'll need to configure the following things :
    73  ```
    74  <build>
    75      <extensions>
    76          <extension>
    77              <groupId>kr.motd.maven</groupId>
    78              <artifactId>os-maven-plugin</artifactId>
    79              <version>1.5.0.Final</version>
    80          </extension>
    81      </extensions>
    82      <plugins>
    83          <plugin>
    84              <groupId>org.xolstice.maven.plugins</groupId>
    85              <artifactId>protobuf-maven-plugin</artifactId>
    86              <version>0.5.0</version>
    87              <configuration>
    88                  <protocArtifact>com.google.protobuf:protoc:3.4.0:exe:${os.detected.classifier}</protocArtifact>
    89                  <pluginId>grpc-java</pluginId>
    90                  <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
    91              </configuration>
    92              <executions>
    93                  <execution>
    94                      <goals>
    95                          <goal>compile</goal>
    96                          <goal>compile-custom</goal>
    97                      </goals>
    98                  </execution>
    99              </executions>
   100          </plugin>
   101      </plugins>
   102  </build>
   103  ```
   104  #### Main.java
   105  Use the code below to set up a channel and client to connect to your `lnd` node.
   106  
   107  Note that when an IP address is used to connect to the node (e.g. 192.168.1.21 instead of localhost) you need to add `--tlsextraip=192.168.1.21` to your `lnd` configuration and re-generate the certificate (delete tls.cert and tls.key and restart lnd).
   108  
   109  ```java
   110  import io.grpc.Attributes;
   111  import io.grpc.CallCredentials;
   112  import io.grpc.ManagedChannel;
   113  import io.grpc.Metadata;
   114  import io.grpc.MethodDescriptor;
   115  import io.grpc.Status;
   116  import io.grpc.netty.GrpcSslContexts;
   117  import io.grpc.netty.NettyChannelBuilder;
   118  import io.netty.handler.ssl.SslContext;
   119  import lnrpc.LightningGrpc;
   120  import lnrpc.LightningGrpc.LightningBlockingStub;
   121  import lnrpc.Rpc.GetInfoRequest;
   122  import lnrpc.Rpc.GetInfoResponse;
   123  import org.apache.commons.codec.binary.Hex;
   124  
   125  import java.io.File;
   126  import java.io.IOException;
   127  import java.nio.file.Files;
   128  import java.nio.file.Paths;
   129  import java.util.concurrent.Executor;
   130  
   131  public class Main {
   132    static class MacaroonCallCredential implements CallCredentials {
   133      private final String macaroon;
   134  
   135      MacaroonCallCredential(String macaroon) {
   136        this.macaroon = macaroon;
   137      }
   138  
   139      public void thisUsesUnstableApi() {}
   140  
   141      public void applyRequestMetadata(
   142          MethodDescriptor < ? , ? > methodDescriptor,
   143          Attributes attributes,
   144          Executor executor,
   145          final MetadataApplier metadataApplier
   146      ) {
   147        String authority = attributes.get(ATTR_AUTHORITY);
   148        System.out.println(authority);
   149        executor.execute(new Runnable() {
   150          public void run() {
   151            try {
   152              Metadata headers = new Metadata();
   153              Metadata.Key < String > macaroonKey = Metadata.Key.of("macaroon", Metadata.ASCII_STRING_MARSHALLER);
   154              headers.put(macaroonKey, macaroon);
   155              metadataApplier.apply(headers);
   156            } catch (Throwable e) {
   157              metadataApplier.fail(Status.UNAUTHENTICATED.withCause(e));
   158            }
   159          }
   160        });
   161      }
   162    }
   163  
   164    private static final String CERT_PATH = "/Users/user/Library/Application Support/Lnd/tls.cert";
   165    private static final String MACAROON_PATH = "/Users/user/Library/Application Support/Lnd/data/chain/bitcoin/simnet/admin.macaroon";
   166    private static final String HOST = "localhost";
   167    private static final int PORT = 10009;
   168  
   169    public static void main(String...args) throws IOException {
   170      SslContext sslContext = GrpcSslContexts.forClient().trustManager(new File(CERT_PATH)).build();
   171      NettyChannelBuilder channelBuilder = NettyChannelBuilder.forAddress(HOST, PORT);
   172      ManagedChannel channel = channelBuilder.sslContext(sslContext).build();
   173  
   174      String macaroon =
   175          Hex.encodeHexString(
   176              Files.readAllBytes(Paths.get(MACAROON_PATH))
   177          );
   178  
   179      LightningBlockingStub stub = LightningGrpc
   180          .newBlockingStub(channel)
   181          .withCallCredentials(new MacaroonCallCredential(macaroon));
   182  
   183  
   184      GetInfoResponse response = stub.getInfo(GetInfoRequest.getDefaultInstance());
   185      System.out.println(response.getIdentityPubkey());
   186    }
   187  }
   188  ```
   189  #### Running the example
   190  Execute the following command in the directory where the **pom.xml** file is located.
   191  ```
   192  mvn compile exec:java -Dexec.mainClass="Main" -Dexec.cleanupDaemonThreads=false
   193  ```
   194  ##### Sample output
   195  ```
   196  [INFO] Scanning for projects...
   197  [INFO] ------------------------------------------------------------------------
   198  [INFO] Detecting the operating system and CPU architecture
   199  [INFO] ------------------------------------------------------------------------
   200  [INFO] os.detected.name: osx
   201  [INFO] os.detected.arch: x86_64
   202  [INFO] os.detected.version: 10.13
   203  [INFO] os.detected.version.major: 10
   204  [INFO] os.detected.version.minor: 13
   205  [INFO] os.detected.classifier: osx-x86_64
   206  [INFO]
   207  [INFO] ------------------------------------------------------------------------
   208  [INFO] Building lightning-client 0.0.1-SNAPSHOT
   209  [INFO] ------------------------------------------------------------------------
   210  [INFO]
   211  [INFO] --- protobuf-maven-plugin:0.5.0:compile (default) @ lightning-client ---
   212  [INFO] Compiling 3 proto file(s) to /Users/user/Documents/Projects/lightningclient/target/generated-sources/protobuf/java
   213  [INFO]
   214  [INFO] --- protobuf-maven-plugin:0.5.0:compile-custom (default) @ lightning-client ---
   215  [INFO] Compiling 3 proto file(s) to /Users/user/Documents/Projects/lightningclient/target/generated-sources/protobuf/grpc-java
   216  [INFO]
   217  [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ lightning-client ---
   218  [INFO] Using 'UTF-8' encoding to copy filtered resources.
   219  [INFO] Copying 0 resource
   220  [INFO] Copying 3 resources
   221  [INFO] Copying 3 resources
   222  [INFO]
   223  [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ lightning-client ---
   224  [INFO] Changes detected - recompiling the module!
   225  [INFO] Compiling 12 source files to /Users/user/Documents/Projects/lightningclient/target/classes
   226  [INFO]
   227  [INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ lightning-client ---
   228  032562215c38dede6f1f2f262ff4c8db58a38ecf889e8e907eee8e4c320e0b5e81
   229  [INFO] ------------------------------------------------------------------------
   230  [INFO] BUILD SUCCESS
   231  [INFO] ------------------------------------------------------------------------
   232  [INFO] Total time: 7.408 s
   233  [INFO] Finished at: 2018-01-13T19:05:49+01:00
   234  [INFO] Final Memory: 30M/589M
   235  [INFO] ------------------------------------------------------------------------
   236  ```
   237  
   238  ### Java proto options
   239  
   240  There are 2 options available that can be used in the *lightning.proto* file :
   241  
   242  * option java_multiple_files = true;
   243  * option java_package = "network.lightning.rpc";
   244  >The package you want to use for your generated Java classes. If no explicit java_package option is given in the .proto file, then by default the proto package (specified using the "package" keyword in the .proto file) will be used. However, proto packages generally do not make good Java packages since proto packages are not expected to start with reverse domain names. If not generating Java code, this option has no effect.