Skip to content

Commit 85934cd

Browse files
committed
Initial mobilev2 implementation
1 parent 7bd2f1a commit 85934cd

31 files changed

+11213
-21
lines changed

.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

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

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) {

config.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -830,9 +830,10 @@ func buildTLSConfigForHttp2(config *Config) (*tls.Config, error) {
830830
if !lnrpc.FileExists(tlsCertPath) &&
831831
!lnrpc.FileExists(tlsKeyPath) {
832832

833+
//TODO(kevin): make this a config option, not a hardcoded flag
833834
certBytes, keyBytes, err := cert.GenCertPair(
834835
defaultSelfSignedCertOrganization, nil, nil,
835-
false, DefaultAutogenValidity,
836+
true, DefaultAutogenValidity,
836837
)
837838
if err != nil {
838839
return nil, fmt.Errorf("failed creating "+

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

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

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

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)