diff --git a/wallets/json-rpc/build.gradle b/wallets/json-rpc/build.gradle
new file mode 100644
index 0000000000..f88f051e13
--- /dev/null
+++ b/wallets/json-rpc/build.gradle
@@ -0,0 +1,11 @@
+plugins {
+ id 'bisq.gradle.plugin.BisqPlugin'
+}
+
+dependencies {
+ implementation 'com.squareup.okhttp3:okhttp:4.10.0'
+ implementation 'com.squareup.moshi:moshi:1.14.0'
+
+ testImplementation libs.assertj.core
+ testImplementation 'com.squareup.okhttp3:mockwebserver:4.10.0'
+}
\ No newline at end of file
diff --git a/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcCall.java b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcCall.java
new file mode 100644
index 0000000000..9fd4cbe2ad
--- /dev/null
+++ b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcCall.java
@@ -0,0 +1,33 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.wallets.json_rpc;
+
+import java.util.UUID;
+
+public class JsonRpcCall {
+ private final String jsonrpc = "2.0";
+ private final String id;
+ private final String method;
+ private final Object params;
+
+ public JsonRpcCall(String method, Object params) {
+ this.id = UUID.randomUUID().toString();
+ this.method = method;
+ this.params = params;
+ }
+}
diff --git a/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcClient.java b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcClient.java
new file mode 100644
index 0000000000..1c8669dc40
--- /dev/null
+++ b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcClient.java
@@ -0,0 +1,66 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.wallets.json_rpc;
+
+import com.squareup.moshi.JsonAdapter;
+import com.squareup.moshi.Moshi;
+import okhttp3.*;
+
+import java.io.IOException;
+import java.util.Objects;
+
+public class JsonRpcClient {
+
+ public static final String AUTHORIZATION_HEADER_NAME = "Authorization";
+
+ private final JsonRpcEndpointSpec rpcEndpointSpec;
+
+ private final OkHttpClient client = new OkHttpClient();
+ private final MediaType jsonMediaType = MediaType.parse("application/json");
+
+ private final Moshi moshi = new Moshi.Builder().build();
+ private final JsonAdapter jsonRpcCallJsonAdapter = moshi.adapter(JsonRpcCall.class);
+
+ public JsonRpcClient(JsonRpcEndpointSpec rpcEndpointSpec) {
+ this.rpcEndpointSpec = rpcEndpointSpec;
+ }
+
+ public R call(RpcCall rpcCall) throws IOException {
+ JsonRpcCall jsonRpcCall = new JsonRpcCall(rpcCall.getRpcMethodName(), rpcCall.request);
+ String jsonRequest = jsonRpcCallJsonAdapter.toJson(jsonRpcCall);
+ Request request = buildRequest(jsonRequest);
+
+ try (Response response = client.newCall(request).execute()) {
+ if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
+
+ ResponseBody responseBody = response.body();
+ Objects.requireNonNull(responseBody);
+
+ JsonAdapter jsonAdapter = rpcCall.getJsonAdapter();
+ return jsonAdapter.fromJson(responseBody.source());
+ }
+ }
+
+ private Request buildRequest(String body) {
+ return new Request.Builder()
+ .url(rpcEndpointSpec.getUrl())
+ .addHeader(AUTHORIZATION_HEADER_NAME, rpcEndpointSpec.getAuthHeaderValue())
+ .post(RequestBody.create(body, jsonMediaType))
+ .build();
+ }
+}
diff --git a/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcEndpointSpec.java b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcEndpointSpec.java
new file mode 100644
index 0000000000..42fb0b6e45
--- /dev/null
+++ b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/JsonRpcEndpointSpec.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.wallets.json_rpc;
+
+import lombok.Getter;
+import okhttp3.Credentials;
+import okhttp3.HttpUrl;
+
+@Getter
+public class JsonRpcEndpointSpec {
+ private final HttpUrl url;
+ private final String username;
+ private final String password;
+
+ public JsonRpcEndpointSpec(String url, String username, String password) {
+ this(HttpUrl.parse(url), username, password);
+ }
+
+ public JsonRpcEndpointSpec(HttpUrl url, String username, String password) {
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getAuthHeaderValue() {
+ return Credentials.basic(username, password);
+ }
+}
diff --git a/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/RpcCall.java b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/RpcCall.java
new file mode 100644
index 0000000000..1b4f197587
--- /dev/null
+++ b/wallets/json-rpc/src/main/java/bisq/wallets/json_rpc/RpcCall.java
@@ -0,0 +1,44 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.wallets.json_rpc;
+
+import com.squareup.moshi.JsonAdapter;
+import com.squareup.moshi.Moshi;
+import lombok.Getter;
+
+public abstract class RpcCall {
+
+ @Getter
+ protected final T request;
+
+ private final Moshi moshi = new Moshi.Builder().build();
+
+ public RpcCall(T request) {
+ this.request = request;
+ }
+
+ public abstract String getRpcMethodName();
+
+ public abstract boolean isResponseValid(R response);
+
+ public abstract Class getRpcResponseClass();
+
+ public JsonAdapter getJsonAdapter() {
+ return moshi.adapter(getRpcResponseClass());
+ }
+}
diff --git a/wallets/json-rpc/src/test/java/bisq/wallets/json_rpc/DummyGetBlockChainInfoRpcCall.java b/wallets/json-rpc/src/test/java/bisq/wallets/json_rpc/DummyGetBlockChainInfoRpcCall.java
new file mode 100644
index 0000000000..df1a2ee911
--- /dev/null
+++ b/wallets/json-rpc/src/test/java/bisq/wallets/json_rpc/DummyGetBlockChainInfoRpcCall.java
@@ -0,0 +1,42 @@
+/*
+ * This file is part of Bisq.
+ *
+ * Bisq is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Bisq is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Bisq. If not, see .
+ */
+
+package bisq.wallets.json_rpc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class DummyGetBlockChainInfoRpcCall extends RpcCall