mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-23 16:14:20 +01:00
Initial version of an esplora backend plugin
This commit is contained in:
committed by
Christian Decker
parent
e56c07eac1
commit
d104baa672
135
sauron/sauron.py
Executable file
135
sauron/sauron.py
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import requests
|
||||
|
||||
from art import sauron_eye
|
||||
from pyln.client import Plugin
|
||||
|
||||
|
||||
plugin = Plugin()
|
||||
|
||||
|
||||
@plugin.init()
|
||||
def init(plugin, options, configuration, **kwargs):
|
||||
plugin.api_endpoint = options.get("sauron-api-endpoint")
|
||||
if not plugin.api_endpoint:
|
||||
raise Exception("You need to specify the sauron-api-endpoint option.")
|
||||
|
||||
plugin.log("Sauron plugin initialized")
|
||||
plugin.log(sauron_eye)
|
||||
|
||||
|
||||
@plugin.method("getchaininfo")
|
||||
def getchaininfo(plugin, **kwargs):
|
||||
blockhash_url = "{}/block-height/0".format(plugin.api_endpoint)
|
||||
blockcount_url = "{}/blocks/tip/height".format(plugin.api_endpoint)
|
||||
chains = {
|
||||
"000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f":
|
||||
"main",
|
||||
"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943":
|
||||
"test",
|
||||
"0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206":
|
||||
"regtest"
|
||||
}
|
||||
|
||||
genesis_req = requests.get(blockhash_url)
|
||||
blockcount_req = requests.get(blockcount_url)
|
||||
assert genesis_req.status_code == 200 and blockcount_req.status_code == 200
|
||||
if genesis_req.text not in chains.keys():
|
||||
raise Exception("Unsupported network")
|
||||
|
||||
# We wouldn't be able to hit it if its bitcoind wasn't synced, so
|
||||
# ibd = false and headercount = blockcount
|
||||
return {
|
||||
"chain": chains[genesis_req.text],
|
||||
"blockcount": blockcount_req.text,
|
||||
"headercount": blockcount_req.text,
|
||||
"ibd": False,
|
||||
}
|
||||
|
||||
|
||||
@plugin.method("getrawblockbyheight")
|
||||
def getrawblock(plugin, height, **kwargs):
|
||||
blockhash_url = "{}/block-height/{}".format(plugin.api_endpoint, height)
|
||||
|
||||
blockhash_req = requests.get(blockhash_url)
|
||||
# FIXME: Esplora doesn't serve raw blocks !
|
||||
# https://github.com/Blockstream/esplora/issues/171
|
||||
block_url = "https://blockchain.info/block/{}?format=hex"
|
||||
block_req = requests.get(block_url.format(blockhash_req.text))
|
||||
if blockhash_req.status_code != 200 or block_req.status_code != 200:
|
||||
return {
|
||||
"blockhash": None,
|
||||
"block": None,
|
||||
}
|
||||
|
||||
return {
|
||||
"blockhash": blockhash_req.text,
|
||||
"block": block_req.text,
|
||||
}
|
||||
|
||||
|
||||
@plugin.method("sendrawtransaction")
|
||||
def sendrawtx(plugin, tx, **kwargs):
|
||||
sendtx_url = "{}/tx".format(plugin.api_endpoint)
|
||||
|
||||
sendtx_req = requests.post(sendtx_url, data=tx)
|
||||
if sendtx_req.status_code != 200:
|
||||
return {
|
||||
"success": False,
|
||||
"errmsg": sendtx_req.text,
|
||||
}
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"errmsg": "",
|
||||
}
|
||||
|
||||
|
||||
@plugin.method("gettxout")
|
||||
def gettxout(plugin, txid, vout, **kwargs):
|
||||
gettx_url = "{}/tx/{}".format(plugin.api_endpoint, txid)
|
||||
status_url = "{}/tx/{}/outspend/{}".format(plugin.api_endpoint, txid, vout)
|
||||
|
||||
gettx_req = requests.get(gettx_url)
|
||||
status_req = requests.get(status_url)
|
||||
assert gettx_req.status_code == status_req.status_code == 200
|
||||
if json.loads(status_req.text)["spent"]:
|
||||
return {
|
||||
"amount": None,
|
||||
"script": None,
|
||||
}
|
||||
|
||||
txo = json.loads(gettx_req.text)["vout"][vout]
|
||||
return {
|
||||
"amount": txo["value"],
|
||||
"script": txo["scriptpubkey"],
|
||||
}
|
||||
|
||||
|
||||
@plugin.method("getfeerate")
|
||||
def getfeerate(plugin, blocks, mode, **kwargs):
|
||||
feerate_url = "{}/fee-estimates".format(plugin.api_endpoint)
|
||||
# Use an estimation provided by esplora
|
||||
if blocks == 100:
|
||||
blocks = 144
|
||||
|
||||
feerate_req = requests.get(feerate_url)
|
||||
assert feerate_req.status_code == 200
|
||||
feerates = json.loads(feerate_req.text)
|
||||
# It renders sat/vB, so * 10**8 / 10**3 for BTC/kB
|
||||
feerate = feerates[str(blocks)] * 10**5
|
||||
|
||||
# FIXME mode ?
|
||||
return {
|
||||
"feerate": int(feerate),
|
||||
}
|
||||
|
||||
|
||||
plugin.add_option(
|
||||
"sauron-api-endpoint",
|
||||
"",
|
||||
"The URL of the esplora instance to hit (including '/api')."
|
||||
)
|
||||
|
||||
plugin.run()
|
||||
Reference in New Issue
Block a user