diff --git a/build.gradle b/build.gradle
index 2bb829fce8..3c4c176b44 100644
--- a/build.gradle
+++ b/build.gradle
@@ -27,6 +27,7 @@ buildscript {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.0'
classpath 'io.fabric.tools:gradle:1.31.0'
+ classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.8"
}
}
diff --git a/dependencies.gradle b/dependencies.gradle
index cb15d49bfb..9e20d378c8 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -54,6 +54,10 @@ ext {
crashlytics_version = '2.10.1'
firebase_core_version = '17.0.1'
+ // Protobuf
+
+ protobuf_java_version = '3.9.2'
+ protoc_version = '3.9.0'
mainApplication = [
kotlin: "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",
@@ -113,4 +117,9 @@ ext {
leakCanary: "com.squareup.leakcanary:leakcanary-android:${leakCanaryVersion}",
leakCanaryNoop: "com.squareup.leakcanary:leakcanary-android-no-op:${leakCanaryVersion}",
]
+
+ protobuf = [
+ protobufJava: "com.google.protobuf:protobuf-java:$protobuf_java_version",
+ protoc: "com.google.protobuf:protoc:$protoc_version"
+ ]
}
\ No newline at end of file
diff --git a/lib-middleware/build.gradle b/lib-middleware/build.gradle
new file mode 100644
index 0000000000..89d4171d41
--- /dev/null
+++ b/lib-middleware/build.gradle
@@ -0,0 +1,2 @@
+configurations.maybeCreate("default")
+artifacts.add("default", file('lib.aar'))
\ No newline at end of file
diff --git a/lib-middleware/lib.aar b/lib-middleware/lib.aar
new file mode 100644
index 0000000000..ad631b6e70
Binary files /dev/null and b/lib-middleware/lib.aar differ
diff --git a/middleware/.gitignore b/middleware/.gitignore
new file mode 100644
index 0000000000..796b96d1c4
--- /dev/null
+++ b/middleware/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/middleware/build.gradle b/middleware/build.gradle
new file mode 100644
index 0000000000..b000d2321c
--- /dev/null
+++ b/middleware/build.gradle
@@ -0,0 +1,39 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+apply plugin: 'kotlin-kapt'
+
+android {
+ def config = rootProject.extensions.getByName("ext")
+
+ compileSdkVersion config["compile_sdk"]
+
+ defaultConfig {
+ minSdkVersion config["min_sdk"]
+ targetSdkVersion config["target_sdk"]
+ testInstrumentationRunner config["test_runner"]
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ implementation project(':lib-middleware')
+ implementation project(':protobuf')
+
+ def applicationDependencies = rootProject.ext.mainApplication
+ def unitTestDependencies = rootProject.ext.unitTesting
+
+ implementation applicationDependencies.kotlin
+ implementation applicationDependencies.timber
+
+ testImplementation unitTestDependencies.junit
+ testImplementation unitTestDependencies.kotlinTest
+ testImplementation unitTestDependencies.mockito
+}
\ No newline at end of file
diff --git a/middleware/proguard-rules.pro b/middleware/proguard-rules.pro
new file mode 100644
index 0000000000..f1b424510d
--- /dev/null
+++ b/middleware/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/middleware/src/main/AndroidManifest.xml b/middleware/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..06e42a2f0e
--- /dev/null
+++ b/middleware/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/middleware/src/main/res/values/strings.xml b/middleware/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..ee878c5487
--- /dev/null
+++ b/middleware/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Middleware
+
diff --git a/protobuf/.gitignore b/protobuf/.gitignore
new file mode 100644
index 0000000000..796b96d1c4
--- /dev/null
+++ b/protobuf/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/protobuf/build.gradle b/protobuf/build.gradle
new file mode 100644
index 0000000000..49a9449a07
--- /dev/null
+++ b/protobuf/build.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'java-library'
+apply plugin: 'com.google.protobuf'
+
+sourceSets{
+ main.java.srcDirs += "${protobuf.generatedFilesBaseDir}/main/java"
+}
+
+dependencies {
+ def protobufDependencies = rootProject.ext.protobuf
+ implementation protobufDependencies.protobufJava
+}
+
+protobuf {
+ protoc {
+ artifact = rootProject.ext.protobuf.protoc
+ }
+}
\ No newline at end of file
diff --git a/protobuf/src/main/proto/commands.proto b/protobuf/src/main/proto/commands.proto
new file mode 100644
index 0000000000..49e8be694d
--- /dev/null
+++ b/protobuf/src/main/proto/commands.proto
@@ -0,0 +1,240 @@
+syntax = "proto3";
+package anytype;
+option go_package = "pb";
+
+import "models.proto";
+
+service ClientCommands {
+ rpc WalletCreate (WalletCreateRequest) returns (WalletCreateResponse);
+ rpc WalletRecover (WalletRecoverRequest) returns (WalletRecoverResponse);
+ rpc AccountCreate (AccountCreateRequest) returns (AccountCreateResponse);
+ rpc AccountSelect (AccountSelectRequest) returns (AccountSelectResponse);
+ rpc ImageGetBlob (ImageGetBlobRequest) returns (ImageGetBlobResponse);
+}
+
+message WalletCreateRequest {
+ string rootPath = 1;
+}
+
+message WalletCreateResponse {
+ Error error = 1;
+ string mnemonic = 2;
+
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+
+ FAILED_TO_CREATE_LOCAL_REPO = 101;
+ // ...
+ }
+ }
+}
+
+message WalletRecoverRequest {
+ string rootPath = 1;
+ string mnemonic = 2;
+}
+
+message WalletRecoverResponse {
+ Error error = 1;
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+
+ FAILED_TO_CREATE_LOCAL_REPO = 101;
+ }
+ }
+}
+
+message AccountCreateRequest {
+ string username = 1;
+ string avatarLocalPath = 2;
+}
+
+message AccountCreateResponse {
+ Error error = 1;
+ Account account = 2;
+
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+
+ ACCOUNT_CREATED_BUT_FAILED_TO_START_NODE = 101;
+ ACCOUNT_CREATED_BUT_FAILED_TO_SET_NAME = 102;
+ ACCOUNT_CREATED_BUT_FAILED_TO_SET_AVATAR = 103;
+ }
+ }
+}
+
+// Start accounts search for recovered mnemonic
+message AccountRecoverRequest {
+}
+
+// Found accounts will come in event AccountAdd
+message AccountRecoverResponse {
+ Error error = 1;
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+ // ...
+ NO_ACCOUNTS_FOUND = 101;
+ NEED_TO_RECOVER_WALLET_FIRST = 102;
+ FAILED_TO_CREATE_LOCAL_REPO = 103;
+ LOCAL_REPO_EXISTS_BUT_CORRUPTED = 104;
+ FAILED_TO_RUN_NODE = 105;
+ }
+ }
+}
+
+message AccountSelectRequest {
+ string id = 1;
+ // optional, set if this is the first request
+ string rootPath = 2;
+}
+
+message AccountSelectResponse {
+ Error error = 1;
+ Account account = 2;
+
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+ // ...
+
+ FAILED_TO_CREATE_LOCAL_REPO = 101;
+ LOCAL_REPO_EXISTS_BUT_CORRUPTED = 102;
+ FAILED_TO_RUN_NODE = 103;
+ FAILED_TO_FIND_ACCOUNT_INFO = 104;
+ LOCAL_REPO_NOT_EXISTS_AND_MNEMONIC_NOT_SET = 105;
+
+ }
+ }
+}
+
+message AccountStartRequest {
+ string id = 1;
+}
+
+message AccountStartResponse {
+ Error error = 1;
+ Account account = 2;
+
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+ // ...
+
+ LOCAL_REPO_DOESNT_EXIST = 101;
+ LOCAL_REPO_EXISTS_BUT_CORRUPTED = 102;
+ FAILED_TO_RUN_NODE = 103;
+ FAILED_TO_FIND_ACCOUNT_INFO = 104;
+ }
+ }
+}
+
+message IpfsGetFileRequest {
+ string id = 1;
+}
+
+message IpfsGetFileResponse {
+ Error error = 1;
+ bytes data = 2;
+ string media = 3;
+ string name = 4;
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+ // ...
+
+ NOT_FOUND = 101;
+ TIMOUT = 102;
+ }
+ }
+}
+
+message IpfsGetDataRequest {
+ string id = 1;
+}
+
+message IpfsGetDataResponse {
+ Error error = 1;
+ oneof data {
+ bytes content = 2;
+ IpfsLinks links = 3;
+ }
+
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+ // ...
+
+ NOT_FOUND = 101;
+ TIMOUT = 102;
+ }
+ }
+}
+
+message ImageGetBlobRequest {
+ string id = 1;
+ ImageSize size = 2;
+}
+
+message ImageGetBlobResponse {
+ Error error = 1;
+ bytes blob = 2;
+
+ message Error {
+ Code code = 1;
+ string description = 2;
+
+ enum Code {
+ NULL = 0;
+ UNKNOWN_ERROR = 1;
+ BAD_INPUT = 2;
+ // ...
+
+ NOT_FOUND = 101;
+ TIMOUT = 102;
+ }
+ }
+}
diff --git a/protobuf/src/main/proto/events.proto b/protobuf/src/main/proto/events.proto
new file mode 100644
index 0000000000..cee43d1938
--- /dev/null
+++ b/protobuf/src/main/proto/events.proto
@@ -0,0 +1,37 @@
+syntax = "proto3";
+package anytype;
+option go_package = "pb";
+
+import "models.proto";
+
+// -------- Middle
+message Event {
+ oneof message {
+ AccountAdd accountAdd = 1;
+ BlockCreate blockCreate = 102;
+ BlockUpdate blockUpdate = 103;
+ BlockRemove blockRemove = 104;
+ }
+}
+
+message AccountAdd {
+ int64 index = 1;
+ Account account = 2;
+}
+
+message BlockCreate {
+ string id = 1;
+ string docId = 2;
+ uint32 pos = 3;
+}
+
+message BlockUpdate {
+ string id = 1;
+ string docId = 2;
+ // ... update info
+}
+
+message BlockRemove {
+ string id = 1;
+ string docId = 2;
+}
diff --git a/protobuf/src/main/proto/models.proto b/protobuf/src/main/proto/models.proto
new file mode 100644
index 0000000000..297b82be5a
--- /dev/null
+++ b/protobuf/src/main/proto/models.proto
@@ -0,0 +1,113 @@
+syntax = "proto3";
+package anytype;
+option go_package = "pb";
+
+message Account {
+ string id = 1;
+ string name = 2;
+ Image avatar = 3;
+}
+
+message IpfsLink {
+ string cid = 1;
+ string name = 2;
+ uint64 size = 3;
+}
+
+enum ImageSize {
+ LARGE = 0;
+ SMALL = 1;
+ THUMB = 2;
+}
+
+message Image {
+ string id = 1;
+ repeated ImageSize sizes = 2;
+}
+
+message IpfsLinks {
+ repeated IpfsLink links = 1;
+}
+
+message Accounts {
+ repeated Account accounts = 1;
+}
+
+message State {
+ repeated DocumentHeader documentHeaders = 1;
+ string currentDocumentId = 2;
+}
+
+message DocumentHeader {
+ string id = 1;
+ string name = 2;
+ string version = 3;
+ string icon = 4;
+}
+
+message Document {
+ DocumentHeader header = 1;
+ repeated Block blocks = 2;
+}
+
+message Text {
+ string content = 1;
+ repeated Mark marks = 2;
+ ContentType contentType = 3;
+}
+
+message Mark {
+ MarkType type = 1;
+}
+
+message Block {
+ string id = 1;
+ oneof content {
+ Text text = 11;
+ // ...
+ }
+}
+
+enum StatusType {
+ SUCCESS = 0;
+ FAILURE = 1;
+ WRONG_MNEMONIC = 2;
+ NOT_FOUND = 3;
+ // ...
+}
+
+enum MarkType {
+ B = 0;
+ I = 1;
+ S = 2;
+ KBD = 3;
+ A = 4;
+}
+
+enum ContentType {
+ P = 0;
+ CODE = 1;
+ H_1 = 2;
+ H_2 = 3;
+ H_3 = 4;
+ H_4 = 5;
+ OL = 6;
+ UL = 7;
+ QUOTE = 8;
+ TOGGLE = 9;
+ CHECK = 10;
+}
+
+enum BlockType {
+ H_GRID = 0;
+ V_GRID = 1;
+ EDITABLE = 2;
+ DIV = 3;
+ VIDEO = 4;
+ IMAGE = 5;
+ PAGE = 6;
+ NEW_PAGE = 7;
+ BOOK_MARK = 8;
+ FILE = 9;
+ DATA_VIEW = 10;
+}
diff --git a/settings.gradle b/settings.gradle
index b5c816652e..f8fc4f7d34 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app', ':core_utils', ':feature_editor', ':feature_desktop', ':feature_login'
+include ':app', ':core_utils', ':feature_editor', ':feature_desktop', ':feature_login', ':lib-middleware', ':middleware', ':protobuf'