mirror of
https://github.com/aljazceru/lspd.git
synced 2025-12-24 01:04:21 +01:00
Add cln channel acceptor
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
const (
|
||||
SubscriberTimeoutOption = "lsp-subscribertimeout"
|
||||
ListenAddressOption = "lsp-listen"
|
||||
channelAcceptScript = "lsp-channel-accept-script"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -43,11 +44,12 @@ var (
|
||||
)
|
||||
|
||||
type ClnPlugin struct {
|
||||
done chan struct{}
|
||||
server *server
|
||||
in *os.File
|
||||
out *bufio.Writer
|
||||
writeMtx sync.Mutex
|
||||
done chan struct{}
|
||||
server *server
|
||||
in *os.File
|
||||
out *bufio.Writer
|
||||
writeMtx sync.Mutex
|
||||
channelAcceptScript string
|
||||
}
|
||||
|
||||
func NewClnPlugin(in, out *os.File) *ClnPlugin {
|
||||
@@ -210,6 +212,20 @@ func (c *ClnPlugin) processRequest(request *Request) {
|
||||
c.handleShutdown(request)
|
||||
case "htlc_accepted":
|
||||
c.handleHtlcAccepted(request)
|
||||
case "openchannel":
|
||||
// handle open channel in a goroutine, because order doesn't matter.
|
||||
go c.handleOpenChannel(request)
|
||||
case "openchannel2":
|
||||
// handle open channel in a goroutine, because order doesn't matter.
|
||||
go c.handleOpenChannel(request)
|
||||
case "getchannelacceptscript":
|
||||
c.sendToCln(&Response{
|
||||
JsonRpc: SpecVersion,
|
||||
Id: request.Id,
|
||||
Result: c.channelAcceptScript,
|
||||
})
|
||||
case "setchannelacceptscript":
|
||||
c.handleSetChannelAcceptScript(request)
|
||||
default:
|
||||
c.sendError(
|
||||
request.Id,
|
||||
@@ -239,14 +255,28 @@ func (c *ClnPlugin) handleGetManifest(request *Request) {
|
||||
"if no subscriber is active. golang duration string.",
|
||||
Default: &DefaultSubscriberTimeout,
|
||||
},
|
||||
},
|
||||
RpcMethods: []*RpcMethod{},
|
||||
Dynamic: true,
|
||||
Hooks: []Hook{
|
||||
{
|
||||
Name: "htlc_accepted",
|
||||
Name: channelAcceptScript,
|
||||
Type: "string",
|
||||
Description: "starlark script for channel acceptor.",
|
||||
},
|
||||
},
|
||||
RpcMethods: []*RpcMethod{
|
||||
{
|
||||
Name: "getchannelacceptscript",
|
||||
Description: "Get the startlark channel acceptor script",
|
||||
},
|
||||
{
|
||||
Name: "setchannelacceptscript",
|
||||
Description: "Set the startlark channel acceptor script",
|
||||
},
|
||||
},
|
||||
Dynamic: true,
|
||||
Hooks: []Hook{
|
||||
{Name: "htlc_accepted"},
|
||||
{Name: "openchannel"},
|
||||
{Name: "openchannel2"},
|
||||
},
|
||||
NonNumericIds: true,
|
||||
Subscriptions: []string{
|
||||
"shutdown",
|
||||
@@ -270,6 +300,31 @@ func (c *ClnPlugin) handleInit(request *Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Get the channel acceptor script option.
|
||||
sc, ok := initMsg.Options[channelAcceptScript]
|
||||
if !ok {
|
||||
c.sendError(
|
||||
request.Id,
|
||||
InvalidParams,
|
||||
fmt.Sprintf("Missing option '%s'", channelAcceptScript),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
c.channelAcceptScript, ok = sc.(string)
|
||||
if !ok {
|
||||
c.sendError(
|
||||
request.Id,
|
||||
InvalidParams,
|
||||
fmt.Sprintf(
|
||||
"Invalid value '%v' for option '%s'",
|
||||
sc,
|
||||
channelAcceptScript,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the listen address option.
|
||||
l, ok := initMsg.Options[ListenAddressOption]
|
||||
if !ok {
|
||||
@@ -382,6 +437,79 @@ func (c *ClnPlugin) handleHtlcAccepted(request *Request) {
|
||||
c.server.Send(idToString(request.Id), &htlc)
|
||||
}
|
||||
|
||||
func (c *ClnPlugin) handleSetChannelAcceptScript(request *Request) {
|
||||
var params []string
|
||||
err := json.Unmarshal(request.Params, ¶ms)
|
||||
if err != nil {
|
||||
c.sendError(
|
||||
request.Id,
|
||||
ParseError,
|
||||
fmt.Sprintf(
|
||||
"Failed to unmarshal setchannelacceptscript params:%s [%s]",
|
||||
err.Error(),
|
||||
request.Params,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
if len(params) >= 1 {
|
||||
c.channelAcceptScript = params[0]
|
||||
}
|
||||
c.sendToCln(&Response{
|
||||
JsonRpc: SpecVersion,
|
||||
Id: request.Id,
|
||||
Result: c.channelAcceptScript,
|
||||
})
|
||||
}
|
||||
|
||||
func unmarshalOpenChannel(request *Request) (r json.RawMessage, err error) {
|
||||
switch request.Method {
|
||||
case "openchannel":
|
||||
var openChannel struct {
|
||||
OpenChannel json.RawMessage `json:"openchannel"`
|
||||
}
|
||||
err = json.Unmarshal(request.Params, &openChannel)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r = openChannel.OpenChannel
|
||||
case "openchannel2":
|
||||
var openChannel struct {
|
||||
OpenChannel json.RawMessage `json:"openchannel2"`
|
||||
}
|
||||
err = json.Unmarshal(request.Params, &openChannel)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r = openChannel.OpenChannel
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
func (c *ClnPlugin) handleOpenChannel(request *Request) {
|
||||
p, err := unmarshalOpenChannel(request)
|
||||
if err != nil {
|
||||
c.sendError(
|
||||
request.Id,
|
||||
ParseError,
|
||||
fmt.Sprintf(
|
||||
"Failed to unmarshal openchannel params:%s [%s]",
|
||||
err.Error(),
|
||||
request.Params,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
result, err := channelAcceptor(c.channelAcceptScript, request.Method, p)
|
||||
if err != nil {
|
||||
log.Printf("channelAcceptor error - request: %s error: %v", request, err)
|
||||
}
|
||||
c.sendToCln(&Response{
|
||||
JsonRpc: SpecVersion,
|
||||
Id: request.Id,
|
||||
Result: result,
|
||||
})
|
||||
}
|
||||
|
||||
// Sends an error to cln.
|
||||
func (c *ClnPlugin) sendError(id json.RawMessage, code int, message string) {
|
||||
// Log the error to cln first.
|
||||
|
||||
Reference in New Issue
Block a user