Skip to content

Commit

Permalink
Merge pull request #14 from feiyu-he/demo/jsonrpc-example-with-double…
Browse files Browse the repository at this point in the history
…type

jsonrpc example with two type
  • Loading branch information
qingfengzxr committed Jul 1, 2024
2 parents 7b49881 + a9dad91 commit 2e30736
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 0 deletions.
44 changes: 44 additions & 0 deletions jsonrpc_example.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
extends Node2D


# Called when the node enters the scene tree for the first time.
func _ready():
#first example: use c++ module
var jsonrpcHelper = JsonrpcHelper.new()
var output = jsonrpcHelper.eth_block_number()
print("example output: ", output)
return

#second example: use HTTPRequest scene
# Create an HTTP request node and connect its completion signal.
var http_request = HTTPRequest.new()
add_child(http_request)
# bind call back function
http_request.request_completed.connect(self._http_request_completed)

# Perform a POST request. The URL below returns JSON as of writing.
# Note: Don't make simultaneous requests using a single HTTPRequest node.
# The snippet below is provided for reference only.
var body = JSON.new().stringify({"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": "get_01"})
var error = http_request.request("https://optimism.llamarpc.com", ['Content-Type: application/json'], HTTPClient.METHOD_POST, body)
if error != OK:
push_error("An error occurred in the HTTP request.")
pass # Replace with function body.

# Called when the HTTP request is completed.
func _http_request_completed(result, response_code, headers, body):
print("response_code: ", response_code, "\n")
print("result: ", result, "\n")
print("headers: ", headers, "\n")
print("body: ", body, "\n")
var json = JSON.new()
json.parse(body.get_string_from_utf8())
var response = json.get_data()

# Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
#print(response.headers["User-Agent"])
print("response: ", response)

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
Binary file modified modules/web3/__pycache__/config.cpython-310.pyc
Binary file not shown.
Binary file modified modules/web3/__pycache__/config.cpython-312.pyc
Binary file not shown.
99 changes: 99 additions & 0 deletions modules/web3/jsonrpc_helper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "jsonrpc_helper.h"
#include <string>
#include <iostream>

JsonrpcHelper::JsonrpcHelper() {
;
}

JsonrpcHelper::~JsonrpcHelper() {
;
}

String JsonrpcHelper::eth_block_number() {
HTTPClient *client = HTTPClient::create();

Vector<String> p_params = Vector<String>();
Dictionary request = make_request("eth_blockNumber", p_params, 1);
String msg = Variant(request).to_json_string();

printf("request msg: %s\n", msg.utf8().get_data());

String host_name = "https://optimism.llamarpc.com";
Error err = client->connect_to_host(host_name, 443, nullptr); // if use http, port is 80
if (err != OK) {
ERR_PRINT("Error connect_to_host.");
return "";
}

// wait connect, it's necessray to wait connect done.
while (client->get_status() == HTTPClient::STATUS_CONNECTING ||
client->get_status() == HTTPClient::STATUS_RESOLVING) {
client->poll();
}

if (client->get_status() != HTTPClient::STATUS_CONNECTED) {
String errmsg = "Error connect 2. status: " + String::num_int64(client->get_status());
ERR_PRINT(errmsg);
return "";
}

Vector<String> headers;
headers.push_back("Content-Type: application/json");
headers.push_back("Content-Length: " + itos(msg.utf8().length()));
headers.push_back("Accept-Encoding: gzip, deflate"); // TODO: maybe needn't

// request need to be uint8_t array
CharString charstr = msg.utf8();
Vector<uint8_t> uint8_array;
for (int i = 0; i < charstr.length(); ++i) {
uint8_array.push_back(static_cast<uint8_t>(charstr[i]));
}

// send post request
err = client->request(HTTPClient::Method::METHOD_POST, "/", headers, uint8_array.ptr(), uint8_array.size());
if (err != OK) {
ERR_PRINT("Error sending request.");
return "";
}

// waiting response
while (client->get_status() == HTTPClient::STATUS_REQUESTING) {
client->poll();
}

if (client->get_status() != HTTPClient::STATUS_BODY &&
client->get_status() != HTTPClient::STATUS_CONNECTED) {
String errmsg = "Error response. status: " + String::num_int64(client->get_status());
ERR_PRINT(errmsg);
return "";
}

// read response body data
PackedByteArray response_body;
while (client->get_status() == HTTPClient::STATUS_BODY) {
client->poll();
PackedByteArray chunk = client->read_response_body_chunk();
if (chunk.size() == 0) {
// waiting more package
OS::get_singleton()->delay_usec(500); // 500us
continue;
}
response_body.append_array(chunk);
}

// change Vector<uint8_t> to String
String response_body_str;
if (response_body.size() > 0) {
response_body_str = String::utf8((const char*)response_body.ptr(), response_body.size());
}

// example output: Response body: {"jsonrpc":"2.0","id":1,"result":"0x74751e4"}
printf("Debug! Response body: %s\n", response_body_str.utf8().get_data());
return response_body_str;
}


void JsonrpcHelper::_bind_methods() {
ClassDB::bind_method(D_METHOD("eth_block_number"), &JsonrpcHelper::eth_block_number);
}
31 changes: 31 additions & 0 deletions modules/web3/jsonrpc_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef JSONRPC_HELPER_H
#define JSONRPC_HELPER_H


#include "core/object/ref_counted.h"
#include "core/string/ustring.h"
#include "core/variant/array.h"
#include "core/variant/variant.h"
#include "core/error/error_macros.h"
#include "core/error/error_list.h"

#include "core/io/http_client.h"
#include "scene/main/http_request.h"
#include "core/io/json.h"
#include "modules/jsonrpc/jsonrpc.h"

class JsonrpcHelper : public JSONRPC {
GDCLASS(JsonrpcHelper, JSONRPC);

protected:
static void _bind_methods();

public:
JsonrpcHelper();
~JsonrpcHelper();

String eth_block_number();
String format_output(const String &p_text);
};

#endif // JSONRPC_HELPER_H
2 changes: 2 additions & 0 deletions modules/web3/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "optimism.h"
#include "legacy_tx.h"
#include "big_int.h"
#include "jsonrpc_helper.h"

void initialize_web3_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
Expand All @@ -19,6 +20,7 @@ void initialize_web3_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<KeccakWrapper>();
ClassDB::register_class<LegacyTx>();
ClassDB::register_class<BigInt>();
ClassDB::register_class<JsonrpcHelper>();
}

void uninitialize_web3_module(ModuleInitializationLevel p_level) {
Expand Down

0 comments on commit 2e30736

Please sign in to comment.