Skip to content

Instantly share code, notes, and snippets.

@RyanKung
Last active December 26, 2023 05:20
Show Gist options
  • Save RyanKung/c68733d512a04856ce9f36e84c1ebb22 to your computer and use it in GitHub Desktop.
Save RyanKung/c68733d512a04856ce9f36e84c1ebb22 to your computer and use it in GitHub Desktop.
poll.py
import platform
import re
import time
import cffi
from eth_account.messages import encode_defunct
from web3 import Web3
import simplejson as json
import asyncio
current_os = platform.system()
if current_os == "Windows":
extension = "dll"
elif current_os == "Darwin":
extension = "dylib"
else:
extension = "so"
ffi = cffi.FFI()
c_header = open("lib/rings.h", "r").read()
c_header = re.sub(r"#define .*", "", c_header)
ffi.cdef(c_header)
rings = ffi.dlopen(f"lib/librings_node.{extension}")
def gen_signer(acc):
@ffi.callback("void (*)(const char *, char *)")
def signer(msg, output):
c_input = ffi.string(msg)
decoded = encode_defunct(c_input)
sig = acc.sign_message(decoded)
ffi.memmove(output, sig.signature, len(sig.signature))
return
return signer
@ffi.callback("void(*)(FFIBackendBehaviour *, ProviderPtr *, char *, char *)")
def default_handler(ins, provider, relay, message):
return
@ffi.callback("void(*)(FFIBackendBehaviour *, ProviderPtr *, char *, char *)")
def on_custom_message(ins, provider, relay, message):
print(message)
return
def request(provider, method, data):
c_data = ffi.new("char[]", data.encode())
c_method = ffi.new("char[]", method.encode())
ret = rings.request(ffi.addressof(provider), c_method, c_data)
ret = ffi.string(ret)
return ret
def create_provider(acc,
on_paintext_message=default_handler,
on_service_message=default_handler,
on_extension_message=default_handler):
rings.init_logging(rings.Debug)
callback = rings.new_ffi_backend_behaviour(on_paintext_message, on_service_message, on_extension_message)
provider = rings.new_provider_with_callback(
"stun://stun.l.google.com".encode(),
10,
acc.address.encode(),
"eip191".encode(),
gen_signer(acc),
ffi.addressof(callback),
)
rings.async_listen(ffi.addressof(provider))
return provider
async def main():
w3 = Web3()
acc = w3.eth.account.create()
provider = create_provider(acc, on_custom_message)
ret = request(provider, "connectPeerViaHttp", json.dumps(["https://<some host>"]))
print("node info:", ret)
while 1:
ret = request(provider, "nodeInfo", json.dumps([]))
if json.loads(ret)['result']['swarm']['connections'][0]['state'] != "Connected":
print("status", ret)
await asyncio.sleep(2)
else:
poll = request(provider, "sendBackendMessage",
json.dumps([
"<node did>",
"{\"PlainText\":\"helloworld\"}"
]))
print("poll", poll)
break
if __name__ == "__main__":
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment