Skip to content

Commit

Permalink
Merge pull request #102 from gudnuf/remove_bolt11
Browse files Browse the repository at this point in the history
Remove BOLT11 Receiving Support; Remove Python 3.8 from CI
  • Loading branch information
farscapian authored Jul 29, 2024
2 parents e76876f + dc2cc08 commit b68102e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
bitcoind-version: ["26.1"]
experimental: [1]
deprecated: [0]
python-version: ["3.8", "3.12"]
python-version: ["3.12"]
os: ["ubuntu-latest"]

runs-on: ${{ matrix.os }}
Expand Down
85 changes: 18 additions & 67 deletions bolt12-prism.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,15 @@ def updateprism(plugin, prism_id, members):


@plugin.method("prism-bindinglist")
def list_bindings(plugin, offer_id=None, invoice_label=""):
def list_bindings(plugin, offer_id=None):
'''Lists all prism bindings.'''

bolt12_prism_response = None

# if an offer_id is not supplied and also an invoice_label, then we return all bindings.
if offer_id == None and invoice_label == "":
# if an offer is not supplied, we return all bindings.
# can use the pnameX in rune construction to restrict this
# https://docs.corelightning.org/reference/lightning-commando-rune
if offer_id == None:

binding_offers = PrismBinding.list_binding_offers(plugin)
prism_response = {
Expand All @@ -145,66 +147,31 @@ def list_bindings(plugin, offer_id=None, invoice_label=""):
f"bolt12_prism_bindings": binding.to_dict()
}

if offer_id == None and invoice_label != "":

# then we're going to return a single binding.
binding = PrismBinding.get(plugin, bind_to=invoice_label, bolt_version="bolt11")

if not binding:
raise Exception("ERROR: could not find a binding for this offer.")

plugin.log(f"prism-bindingslist executed for '{offer_id}'", "info")

prism_response = {
f"bolt11_prism_bindings": binding.to_dict()
}

return prism_response



# adds a binding to the database.
@plugin.method("prism-bindingadd")
def bindprism(plugin: Plugin, prism_id, offer_id=None, invoice_label=""):
'''Binds a prism to a BOLT12 Offer or a BOLT11 invoice.'''
def bindprism(plugin: Plugin, prism_id, offer_id=None):
'''Binds a prism to a BOLT12 Offer.'''

plugin.log(f"In bindprism with prism_id={prism_id} and offer_id={offer_id}.", "info")

trigger = None

bolt_version = None
bind_to = None
if offer_id == None and invoice_label != "":
bolt_version = "bolt11"
bind_to = invoice_label
elif offer_id != None:
bolt_version = "bolt12"
bind_to = offer_id
else:
raise Exception("bindprism was has some issues.")

# ensure the offer/invoice exists
if bolt_version == "bolt12":
trigger = plugin.rpc.listoffers(offer_id=offer_id)["offers"]
if offer_id is None:
raise Exception("You must provide an offer_id!")

if [trigger] == []:
raise Exception("ERROR: the bolt12 offer does not exist!")
trigger = plugin.rpc.listoffers(offer_id=offer_id)["offers"]

elif bolt_version == "bolt11":
trigger = plugin.rpc.listinvoices(label=invoice_label)["invoices"]
if [trigger] == []:
raise Exception("ERROR: the bolt12 offer does not exist!")

if trigger == []:
raise Exception("ERROR: the bolt11 invoice does not exist.")

add_binding_result = PrismBinding.add_binding(
plugin=plugin, bind_to=bind_to, prism_id=prism_id,
bolt_version=bolt_version
)
add_binding_result = PrismBinding.add_binding(plugin=plugin, prism_id=prism_id, offer_id=offer_id)

return add_binding_result



# set the outlay for a binding-member.
@plugin.method("prism-setoutlay")
def set_binding_member_outlay(plugin: Plugin, offer_id=None, member_id=None, new_outlay_msat=0):
Expand Down Expand Up @@ -233,24 +200,19 @@ def set_binding_member_outlay(plugin: Plugin, offer_id=None, member_id=None, new
return prism_response

@plugin.method("prism-bindingremove")
def remove_prism_binding(plugin, offer_id=None, invoice_label=""):
def remove_prism_binding(plugin, offer_id=None):
'''Removes a prism binding.'''

## TODO implement invoice_label
bolt_version = "bolt12"
if invoice_label != "" and offer_id == None:
bolt_version = "bolt11"

try:
binding = PrismBinding.get(plugin, offer_id, bolt_version)
binding = PrismBinding.get(plugin, offer_id)

if not binding:
raise Exception("ERROR: could not find a binding for this offer.")

plugin.log(f"Attempting to delete a prism binding for {offer_id}.", "info")

recordDeleted = False
recordDeleted = PrismBinding.delete(plugin, bind_to=offer_id)
recordDeleted = PrismBinding.delete(plugin, offer_id=offer_id)

return { "binding_removed": recordDeleted }

Expand Down Expand Up @@ -319,22 +281,15 @@ def on_payment(plugin, invoice_payment, **kwargs):
if invoice is None:
return

bind_to = None
bolt_version = None

# invoices will likely be generated from BOLT 12
if "local_offer_id" in invoice:
bind_to = invoice["local_offer_id"]
bolt_version = "bolt12"
else:
bind_to = payment_label
bolt_version = "bolt11"
offer_id = invoice["local_offer_id"]

# TODO: return PrismBinding.get as class member rather than json
binding = None

try:
binding = PrismBinding.get(plugin, bind_to, bolt_version)
binding = PrismBinding.get(plugin, offer_id)
except Exception as e:
plugin.log("Incoming payment not associated with prism binding. Skipping.", "info")
return
Expand All @@ -344,8 +299,4 @@ def on_payment(plugin, invoice_payment, **kwargs):
plugin.log(f"amount_msat: {amount_msat}")
binding.pay(amount_msat=int(amount_msat))

# invoices can only be paid once, so we delete the bolt11 binding
if bolt_version == "bolt11":
PrismBinding.delete(plugin, bind_to, bolt_version=bolt_version)

plugin.run() # Run our plugin
49 changes: 17 additions & 32 deletions lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def pay(self, amount_msat: int, binding = None):
invoice = bolt12_invoice.get("invoice")

if invoice is not None:
payment = self._plugin.rpc.pay(bolt11=invoice)
payment = self._plugin.rpc.pay(invoice)
self._plugin.log(f"bolt12_payment: {payment}")
else:
self._plugin.log(f"Could not fetch an invoice from the remote peer.", "warn")
Expand Down Expand Up @@ -383,15 +383,10 @@ class PrismBinding:
prism: Prism

@staticmethod
def delete(plugin: Plugin, bind_to: str, bolt_version="bolt12"):
# TODO: below code is repeated from PrismBinding.get()
types = ["bolt11", "bolt12"]
if bolt_version not in types:
raise Exception(
"ERROR: 'type' MUST be either 'bolt12' or 'bolt11'.")
def delete(plugin: Plugin, offer_id: str):

bindings_key = ["prism", prism_db_version,
"bind", bolt_version, bind_to]
"bind", "bolt12", offer_id]

binding_records = {}
try:
Expand All @@ -402,13 +397,13 @@ def delete(plugin: Plugin, bind_to: str, bolt_version="bolt12"):

if not binding_records:
raise Exception(
f"Could not find a prism binding for offer {bind_to}")
f"Could not find a prism binding for offer {offer_id}")


return binding_records

@staticmethod
def from_db_string(plugin: Plugin, string: str, bind_to: str, bolt_version: str):
def from_db_string(plugin: Plugin, string: str, offer_id: str):
parsed = json.loads(string)

prism_id = parsed.get('prism_id', None)
Expand All @@ -421,18 +416,13 @@ def from_db_string(plugin: Plugin, string: str, bind_to: str, bolt_version: str)
if not member_outlays:
raise Exception("Invalid binding. Missing member_outlays")

return PrismBinding(plugin, timestamp=timestamp, outlays=member_outlays, offer_id=bind_to, prism_id=prism_id, bolt_version=bolt_version)
return PrismBinding(plugin, timestamp=timestamp, outlays=member_outlays, offer_id=offer_id, prism_id=prism_id)

@staticmethod
def get(plugin: Plugin, bind_to: str, bolt_version="bolt12"):

types = ["bolt11", "bolt12"]
if bolt_version not in types:
raise Exception(
"ERROR: 'type' MUST be either 'bolt12' or 'bolt11'.")
def get(plugin: Plugin, offer_id: str):

bindings_key = ["prism", prism_db_version,
"bind", bolt_version, bind_to]
"bind", "bolt12", offer_id]

binding_records = plugin.rpc.listdatastore(
key=bindings_key).get("datastore", [])
Expand All @@ -441,7 +431,7 @@ def get(plugin: Plugin, bind_to: str, bolt_version="bolt12"):
raise Exception(
f"Could not find: {bindings_key}")

return PrismBinding.from_db_string(plugin, string=binding_records[0].get('string'), bind_to=bind_to, bolt_version=bolt_version)
return PrismBinding.from_db_string(plugin, string=binding_records[0].get('string'), offer_id=offer_id)

@staticmethod
def set_member_outlay(binding: None, member_id: str, new_outlay_value=0):
Expand All @@ -459,10 +449,10 @@ def set_member_outlay(binding: None, member_id: str, new_outlay_value=0):
# but keyed on offer_id, as stored in the database.

@staticmethod
def add_binding(plugin: Plugin, bind_to: str, prism_id: str, bolt_version="bolt12"):
def add_binding(plugin: Plugin, prism_id: str, offer_id: str, ):

prism_binding_key = ["prism", prism_db_version,
"bind", bolt_version, bind_to]
"bind", "bolt12", offer_id]

# first we need to see if there are any existing binding records for this prism_id/invoice_type
# plugin.log(f"prism_binding_key: {prism_binding_key}")
Expand Down Expand Up @@ -499,7 +489,7 @@ def add_binding(plugin: Plugin, bind_to: str, prism_id: str, bolt_version="bolt
response = {
"status": dbmode,
"timestamp": timestamp,
"offer_id": bind_to,
"offer_id": offer_id,
"prism_id": prism_id,
"prism_binding_key": prism_binding_key,
"prism_members": [member.to_dict() for member in members]
Expand All @@ -508,13 +498,9 @@ def add_binding(plugin: Plugin, bind_to: str, prism_id: str, bolt_version="bolt
return response

@staticmethod
def list_binding_offers(plugin, bolt_version="bolt12"):
types = ["bolt11", "bolt12"]
if bolt_version not in types:
raise Exception(
"ERROR: 'type' MUST be either 'bolt12' or 'bolt11'.")
def list_binding_offers(plugin):

bindings_key = ["prism", prism_db_version, "bind", bolt_version]
bindings_key = ["prism", prism_db_version, "bind", "bolt12"]

binding_records = plugin.rpc.listdatastore(
key=bindings_key).get("datastore", [])
Expand All @@ -525,7 +511,7 @@ def list_binding_offers(plugin, bolt_version="bolt12"):
offer_id = binding_record["key"][4]
#plugin.log(f"offer_id: {offer_id}")
binding_record_str = binding_record['string']
binding = PrismBinding.from_db_string(plugin, string=binding_record_str, bind_to=offer_id, bolt_version=bolt_version)
binding = PrismBinding.from_db_string(plugin, string=binding_record_str, offer_id=offer_id)
bindings.append(binding)

return bindings
Expand All @@ -534,12 +520,11 @@ def list_binding_offers(plugin, bolt_version="bolt12"):
def datastore_key(self):
return self._datastore_key

def __init__(self, plugin: Plugin, timestamp: int, outlays, offer_id, prism_id, bolt_version="bolt12", binding_dict=None):
def __init__(self, plugin: Plugin, timestamp: int, outlays, offer_id, prism_id, binding_dict=None):

self._plugin = plugin
self.offer_id = offer_id
self.timestamp = timestamp
self.bolt_version = bolt_version
self.members = None

self.prism = Prism.get(plugin, prism_id)
Expand All @@ -551,7 +536,7 @@ def __init__(self, plugin: Plugin, timestamp: int, outlays, offer_id, prism_id,
self.members = binding_dict

self._datastore_key = ["prism", prism_db_version,
"bind", bolt_version, offer_id]
"bind", "bolt12", offer_id]

def to_dict(self):

Expand Down

0 comments on commit b68102e

Please sign in to comment.