Skip to content

Commit 565b05b

Browse files
committed
Initial mobilev2 implementation
1 parent 7bd2f1a commit 565b05b

32 files changed

+12532
-22
lines changed

Diff for: .gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ litcli-debug
88
# MacOS junk
99
.DS_Store
1010

11+
# Files from mobile build.
12+
mobile/build
13+
mobile/*_generated.go
14+
1115
itest/btcd-itest
1216
itest/litd-itest
1317
itest/lnd-itest
1418
itest/itest.test
1519
itest/.logs
16-
itest/*.log
20+
itest/*.log

Diff for: Makefile

+41
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
PKG := github.com/lightninglabs/lightning-terminal
2+
MOBILE_PKG := $(PKG)/mobile
23
ESCPKG := github.com\/lightninglabs\/lightning-terminal
34
LND_PKG := github.com/lightningnetwork/lnd
45
LOOP_PKG := github.com/lightninglabs/loop
@@ -13,6 +14,13 @@ TOOLS_DIR := tools
1314
GO_BIN := ${GOPATH}/bin
1415
GOACC_BIN := $(GO_BIN)/go-acc
1516
GOIMPORTS_BIN := $(GO_BIN)/gosimports
17+
GOMOBILE_BIN := GO111MODULE=off $(GO_BIN)/gomobile
18+
19+
MOBILE_BUILD_DIR :=${GOPATH}/src/$(MOBILE_PKG)/build
20+
IOS_BUILD_DIR := $(MOBILE_BUILD_DIR)/ios
21+
IOS_BUILD := $(IOS_BUILD_DIR)/Litdmobile.xcframework
22+
ANDROID_BUILD_DIR := $(MOBILE_BUILD_DIR)/android
23+
ANDROID_BUILD := $(ANDROID_BUILD_DIR)/Litdmobile.aar
1624

1725
COMMIT := $(shell git describe --abbrev=40 --dirty --tags)
1826
COMMIT_HASH := $(shell git rev-parse HEAD)
@@ -247,3 +255,36 @@ clean:
247255
$(RM) ./litcli-debug
248256
$(RM) ./litd-debug
249257
$(RM) coverage.txt
258+
259+
# =============
260+
# MOBILE
261+
# =============
262+
mobile-rpc:
263+
@$(call print, "Creating mobile RPC from protos.")
264+
cd ./litrpc; COMPILE_MOBILE=1 SUBSERVER_PREFIX=1 ./gen_protos_docker.sh
265+
266+
vendor:
267+
@$(call print, "Re-creating vendor directory.")
268+
rm -r vendor/; go mod vendor
269+
270+
apple: vendor mobile-rpc
271+
@$(call print, "Building iOS and macOS cxframework ($(IOS_BUILD)).")
272+
mkdir -p $(IOS_BUILD_DIR)
273+
$(GOMOBILE_BIN) bind -target=ios,iossimulator,macos -tags="mobile $(RELEASE_LDFLAGS)" -v -o $(IOS_BUILD) $(MOBILE_PKG)
274+
275+
ios: vendor mobile-rpc
276+
@$(call print, "Building iOS cxframework ($(IOS_BUILD)).")
277+
mkdir -p $(IOS_BUILD_DIR)
278+
$(GOMOBILE_BIN) bind -target=ios,iossimulator -tags="mobile $(RELEASE_LDFLAGS)" -v -o $(IOS_BUILD) $(MOBILE_PKG)
279+
280+
macos: vendor mobile-rpc
281+
@$(call print, "Building macOS cxframework ($(IOS_BUILD)).")
282+
mkdir -p $(IOS_BUILD_DIR)
283+
$(GOMOBILE_BIN) bind -target=macos -tags="mobile $(RELEASE_LDFLAGS)" -v -o $(IOS_BUILD) $(MOBILE_PKG)
284+
285+
android: vendor mobile-rpc
286+
@$(call print, "Building Android library ($(ANDROID_BUILD)).")
287+
mkdir -p $(ANDROID_BUILD_DIR)
288+
$(GOMOBILE_BIN) bind -target=android -androidapi 21 -tags="mobile $(LND_RELEASE_TAGS)" -v -o $(ANDROID_BUILD) $(MOBILE_PKG)
289+
290+
mobile: ios android

Diff for: cmd/litd/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
// main starts the lightning-terminal application.
1313
func main() {
14-
err := terminal.New().Run()
14+
err := terminal.New(nil, nil).Run()
1515
var flagErr *flags.Error
1616
isFlagErr := errors.As(err, &flagErr)
1717
if err != nil && (!isFlagErr || flagErr.Type != flags.ErrHelp) {

Diff for: config.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ type Config struct {
161161
LetsEncryptDir string `long:"letsencryptdir" description:"The directory where the Let's Encrypt library will store its key and certificate."`
162162
LetsEncryptListen string `long:"letsencryptlisten" description:"The IP:port on which LiT will listen for Let's Encrypt challenges. Let's Encrypt will always try to contact on port 80. Often non-root processes are not allowed to bind to ports lower than 1024. This configuration option allows a different port to be used, but must be used in combination with port forwarding from port 80. This configuration can also be used to specify another IP address to listen on, for example an IPv6 address."`
163163

164-
TLSCertPath string `long:"tlscertpath" description:"Path to write the self signed TLS certificate for LiT's RPC and REST proxy service (if Let's Encrypt is not used). This only applies to the HTTPSListen port."`
165-
TLSKeyPath string `long:"tlskeypath" description:"Path to write the self signed TLS private key for LiT's RPC and REST proxy service (if Let's Encrypt is not used). This only applies to the HTTPSListen port."`
164+
TLSCertPath string `long:"tlscertpath" description:"Path to write the self signed TLS certificate for LiT's RPC and REST proxy service (if Let's Encrypt is not used). This only applies to the HTTPSListen port."`
165+
TLSKeyPath string `long:"tlskeypath" description:"Path to write the self signed TLS private key for LiT's RPC and REST proxy service (if Let's Encrypt is not used). This only applies to the HTTPSListen port."`
166+
TLSDisableAutofill bool `long:"tlsdisableautofill" description:"Do not include the interface IPs or the system hostname in TLS certificate"`
166167

167168
LitDir string `long:"lit-dir" description:"The main directory where LiT looks for its configuration file. If LiT is running in 'remote' lnd mode, this is also the directory where the TLS certificates and log files are stored by default."`
168169
ConfigFile string `long:"configfile" description:"Path to LiT's configuration file."`
@@ -826,13 +827,15 @@ func buildTLSConfigForHttp2(config *Config) (*tls.Config, error) {
826827
} else {
827828
tlsCertPath := config.TLSCertPath
828829
tlsKeyPath := config.TLSKeyPath
830+
tlsDisableAutoFill := config.TLSDisableAutofill
829831

830832
if !lnrpc.FileExists(tlsCertPath) &&
831833
!lnrpc.FileExists(tlsKeyPath) {
832834

835+
//TODO(kevin): make this a config option, not a hardcoded flag
833836
certBytes, keyBytes, err := cert.GenCertPair(
834837
defaultSelfSignedCertOrganization, nil, nil,
835-
false, DefaultAutogenValidity,
838+
tlsDisableAutoFill, DefaultAutogenValidity,
836839
)
837840
if err != nil {
838841
return nil, fmt.Errorf("failed creating "+

Diff for: litrpc/Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ RUN cd /tmp \
1919
&& go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@${PROTOC_GEN_GO_GRPC_VERSION} \
2020
&& go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@${GRPC_GATEWAY_VERSION} \
2121
&& go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@${GRPC_GATEWAY_VERSION} \
22+
&& go install golang.org/x/tools/cmd/[email protected] \
2223
&& go install github.com/lightninglabs/falafel@${FALAFEL_VERSION}
2324

2425
WORKDIR /build

Diff for: litrpc/gen_protos.sh

+7-1
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,10 @@ popd
5959
pushd autopilotserverrpc
6060
format
6161
generate no-rest
62-
popd
62+
popd
63+
64+
if [[ "$COMPILE_MOBILE" == "1" ]]; then
65+
pushd mobile
66+
./gen_bindings.sh $FALAFEL_VERSION
67+
popd
68+
fi

Diff for: litrpc/gen_protos_docker.sh

+2
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@ docker run \
1919
--rm \
2020
--user $UID:$UID \
2121
-e UID=$UID \
22+
-e COMPILE_MOBILE \
23+
-e SUBSERVER_PREFIX \
2224
-v "$DIR/../:/build" \
2325
lit-protobuf-builder

Diff for: mobile/README.md

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# Building mobile libraries
2+
3+
## Prerequisites
4+
5+
To build for iOS, you need to run macOS with either
6+
[Command Line Tools](https://developer.apple.com/download/all/?q=command%20line%20tools)
7+
or [Xcode](https://apps.apple.com/app/xcode/id497799835) installed.
8+
9+
To build for Android, you need either
10+
[Android Studio](https://developer.android.com/studio) or
11+
[Command Line Tools](https://developer.android.com/studio#downloads) installed, which in turn must be used to install [Android NDK](https://developer.android.com/ndk/).
12+
13+
14+
### Go and Go mobile
15+
16+
First, follow the instructions to [install Go](https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md#building-a-development-version-from-source).
17+
18+
Then, install [Go mobile](https://github.com/golang/go/wiki/Mobile) and
19+
initialize it:
20+
21+
```shell
22+
⛰ go install golang.org/x/mobile/cmd/gomobile@latest
23+
⛰ go mod download golang.org/x/mobile
24+
⛰ gomobile init
25+
```
26+
27+
### Docker
28+
29+
Install and run [Docker](https://www.docker.com/products/docker-desktop).
30+
31+
### Make
32+
33+
Check that `make` is available by running the following command without errors:
34+
35+
```shell
36+
⛰ make --version
37+
```
38+
39+
## Building the libraries
40+
41+
Note that `gomobile` only supports building projects from `$GOPATH` at this
42+
point. However, with the introduction of Go modules, the source code files are
43+
no longer installed there by default.
44+
45+
To be able to do so, we must turn off module and using the now deprecated
46+
`go get` command before turning modules back on again.
47+
48+
```shell
49+
⛰ go env -w GO111MODULE="off"
50+
⛰ go get github.com/lightninglabs/lightning-terminal
51+
⛰ go get golang.org/x/mobile/bind
52+
⛰ go env -w GO111MODULE="on"
53+
```
54+
55+
Finally, let’s change directory to the newly created lightning-terminal folder inside `$GOPATH`:
56+
57+
```shell
58+
cd $GOPATH/src/github.com/lightninglabs/lightning-terminal
59+
```
60+
61+
It is not recommended building from the master branch for mainnet. To checkout
62+
the latest tagged release of Lightning Terminal, run
63+
64+
```shell
65+
⛰ git checkout $(git describe --match "v[0-9]*" --abbrev=0)
66+
```
67+
68+
### iOS
69+
70+
```shell
71+
⛰ make ios
72+
```
73+
74+
The Xcode framework file will be found in `mobile/build/ios/Litdmobile.xcframework`.
75+
76+
### Android
77+
78+
```shell
79+
⛰ make android
80+
```
81+
82+
The AAR library file will be found in `mobile/build/android/Litdmobile.aar`.
83+
84+
---
85+
Tip: `make mobile` will build both iOS and Android libraries.
86+
87+
---
88+
89+
## Generating proto definitions
90+
91+
In order to call the methods in the generated library, the serialized proto for
92+
the given RPC call must be provided. Similarly, the response will be a
93+
serialized proto.
94+
95+
### iOS
96+
97+
In order to generate protobuf definitions for iOS, add `--swift_out=.` to the
98+
first `protoc` invocation found in [ `gen_protos.sh` ](../lnrpc/gen_protos.sh).
99+
100+
Then, some changes to [Dockerfile](../lnrpc/Dockerfile) need to be done in
101+
order to use the [Swift protobuf](https://github.com/apple/swift-protobuf)
102+
plugin with protoc:
103+
104+
1. Replace the base image with `FROM swift:focal` so that Swift can be used.
105+
2. `clang-format='1:7.0*'` is unavailable in Ubuntu Focal. Change that to
106+
`clang-format='1:10.0*'`.
107+
3. On the next line, install Go and set the environment variables by adding the
108+
following commands:
109+
110+
```
111+
RUN apt-get install -y wget \
112+
&& wget -c https://golang.org/dl/go1.17.6.linux-amd64.tar.gz -O - \
113+
| tar -xz -C /usr/local
114+
ENV GOPATH=/go
115+
ENV PATH=$PATH:/usr/local/go/bin:/go/bin
116+
```
117+
118+
4. At the end of the file, just above `CMD`, add the following `RUN` command.
119+
This will download and compile the latest tagged release of Swift protobuf.
120+
121+
```
122+
RUN git clone https://github.com/apple/swift-protobuf.git \
123+
&& cd swift-protobuf \
124+
&& git checkout $(git describe --tags --abbrev=0) \
125+
&& swift build -c release \
126+
&& mv .build/release/protoc-gen-swift /bin
127+
```
128+
129+
Finally, run `make rpc`.
130+
131+
Tip: The generated Swift files will be found in various folders. If you’d like
132+
to move them to the same folder as the framework file, run
133+
134+
```shell
135+
⛰ find . -name "*.swift" -print0 | xargs -0 -I {} mv {} mobile/build/ios
136+
```
137+
138+
`Litdmobile.xcframework` and all Swift files should now be added to your Xcode
139+
project. You will also need to add [Swift Protobuf](https://github.com/apple/swift-protobuf)
140+
to your project to support the generated code.
141+
142+
### Android
143+
144+
#### First option:
145+
146+
In order to generate protobuf definitions for Android, add `--java_out=.`
147+
148+
to the first `protoc` invocation found in
149+
[ `gen_protos.sh` ](../lnrpc/gen_protos.sh). Then, run `make rpc`.
150+
151+
152+
#### Second option (preferable):
153+
154+
- You have to install the profobuf plugin to your Android application.
155+
Please, follow this link https://github.com/google/protobuf-gradle-plugin.
156+
- Add this line to your `app build.gradle` file.
157+
```shell
158+
classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.17"
159+
```
160+
- Create a `proto` folder under the `main` folder.
161+
162+
![proto_folder](docs/proto_folder.png)
163+
164+
- Add `aar` file to libs folder.
165+
166+
- After that add these lines to your `module's` `build.gradle` file:
167+
168+
```shell
169+
plugins {
170+
id "com.google.protobuf"
171+
}
172+
173+
android {
174+
sourceSets {
175+
main {
176+
proto {
177+
178+
}
179+
}
180+
}
181+
}
182+
183+
dependencies {
184+
implementation fileTree(dir: "libs", include: ["*.jar"])
185+
implementation "com.google.protobuf:protobuf-javalite:${rootProject.ext.javalite_version}"
186+
}
187+
188+
protobuf {
189+
protoc {
190+
artifact = "com.google.protobuf:protoc:${rootProject.ext.protoc_version}"
191+
}
192+
generateProtoTasks {
193+
all().each { task ->
194+
task.builtins {
195+
java {
196+
option "lite"
197+
}
198+
}
199+
}
200+
}
201+
}
202+
```
203+
- Then, copy all the proto files from `lnd/lnrpc` to your `proto` folder, saving the structure.
204+
- Build the project and wait until you see the generated Java proto files in the `build` folder.
205+
206+
207+
---
208+
*Note:*
209+
210+
If Android Studio tells you that the `aar` file cannot be included into the `app-bundle`, this is a workaround:
211+
212+
1. Create a separate gradle module
213+
2. Remove everything from there and leave only `aar` and `build.gradle`.
214+
215+
![separate_gradle_module](docs/separate_gradle_module.png)
216+
217+
3. Gradle file should contain only these lines:
218+
219+
```shell
220+
configurations.maybeCreate("default")
221+
artifacts.add("default", file('Litdmobile.aar'))
222+
```
223+
224+
4. In `dependencies` add this line instead of depending on `libs` folder:
225+
```shell
226+
implementation project(":litdmobile", { "default" })
227+
```
228+
---
229+
230+
## Calling the API
231+
232+
In LND v0.15+ all API methods have prefixed the generated methods with the subserver name. This is required to support subservers with name conflicts.
233+
234+
eg. `QueryScores` is now `AutopilotQueryScores`. `GetBlockHeader` is now `NeutrinoKitGetBlockHeader`.
235+
236+
## API docs
237+
238+
- [LND gRPC API Reference](https://api.lightning.community)
239+
- [LND Builder’s Guide](https://docs.lightning.engineering)

0 commit comments

Comments
 (0)