@ -1,3 +1,4 @@
from binascii import hexlify
from collections import OrderedDict
from collections import OrderedDict
from enum import Enum
from enum import Enum
from . lightning import LightningRpc , Millisatoshi
from . lightning import LightningRpc , Millisatoshi
@ -5,6 +6,7 @@ from threading import RLock
import inspect
import inspect
import json
import json
import math
import os
import os
import re
import re
import sys
import sys
@ -99,10 +101,37 @@ class Plugin(object):
"""
"""
def __init__ ( self , stdout = None , stdin = None , autopatch = True , dynamic = True ) :
def __init__ ( self , stdout = None , stdin = None , autopatch = True , dynamic = True ,
init_features = None , node_features = None , invoice_features = None ) :
self . methods = { ' init ' : Method ( ' init ' , self . _init , MethodType . RPCMETHOD ) }
self . methods = { ' init ' : Method ( ' init ' , self . _init , MethodType . RPCMETHOD ) }
self . options = { }
self . options = { }
def convert_featurebits ( bits ) :
""" Convert the featurebits into the bytes required to hexencode.
"""
if bits is None :
return None
elif isinstance ( bits , int ) :
bitlen = math . ceil ( math . log ( bits , 256 ) )
return hexlify ( bits . to_bytes ( bitlen , ' big ' ) ) . decode ( ' ASCII ' )
elif isinstance ( bits , str ) :
# Assume this is already hex encoded
return bits
elif isinstance ( bits , bytes ) :
return hexlify ( bits ) . decode ( ' ASCII ' )
else :
raise ValueError ( " Could not convert featurebits to hex-encoded string " )
self . featurebits = {
' init ' : convert_featurebits ( init_features ) ,
' node ' : convert_featurebits ( node_features ) ,
' invoice ' : convert_featurebits ( invoice_features ) ,
}
# A dict from topics to handler functions
# A dict from topics to handler functions
self . subscriptions = { }
self . subscriptions = { }
@ -523,14 +552,21 @@ class Plugin(object):
if method . long_desc :
if method . long_desc :
methods [ len ( methods ) - 1 ] [ " long_description " ] = method . long_desc
methods [ len ( methods ) - 1 ] [ " long_description " ] = method . long_desc
return {
manifest = {
' options ' : list ( self . options . values ( ) ) ,
' options ' : list ( self . options . values ( ) ) ,
' rpcmethods ' : methods ,
' rpcmethods ' : methods ,
' subscriptions ' : list ( self . subscriptions . keys ( ) ) ,
' subscriptions ' : list ( self . subscriptions . keys ( ) ) ,
' hooks ' : hooks ,
' hooks ' : hooks ,
' dynamic ' : self . dynamic
' dynamic ' : self . dynamic ,
}
}
# Compact the features a bit, not important.
features = { k : v for k , v in self . featurebits . items ( ) if v is not None }
if features is not None :
manifest [ ' featurebits ' ] = features
return manifest
def _init ( self , options , configuration , request ) :
def _init ( self , options , configuration , request ) :
self . rpc_filename = configuration [ ' rpc-file ' ]
self . rpc_filename = configuration [ ' rpc-file ' ]
self . lightning_dir = configuration [ ' lightning-dir ' ]
self . lightning_dir = configuration [ ' lightning-dir ' ]