Skip to content

Commit 40d026e

Browse files
authored
Merge pull request #28 from EduardMikhrin/master
glightning: added the emit and subscribe functionality for custom eve…
2 parents 721c341 + d19ee9f commit 40d026e

2 files changed

Lines changed: 107 additions & 28 deletions

File tree

glightning/plugin.go

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,12 +1091,22 @@ func (fb *FeatureBits) AreSet() bool {
10911091
}
10921092

10931093
type Manifest struct {
1094-
Options []Option `json:"options"`
1095-
RpcMethods []*RpcMethod `json:"rpcmethods"`
1096-
Dynamic bool `json:"dynamic"`
1097-
Subscriptions []string `json:"subscriptions,omitempty"`
1098-
Hooks []Hook `json:"hooks,omitempty"`
1099-
FeatureBits *FeatureBits `json:"featurebits,omitempty"`
1094+
Options []Option `json:"options"`
1095+
RpcMethods []*RpcMethod `json:"rpcmethods"`
1096+
Dynamic bool `json:"dynamic"`
1097+
Subscriptions []string `json:"subscriptions,omitempty"`
1098+
Hooks []Hook `json:"hooks,omitempty"`
1099+
FeatureBits *FeatureBits `json:"featurebits,omitempty"`
1100+
Notifications []NotificationTopic `json:"notifications,omitempty"`
1101+
}
1102+
1103+
type NotificationTopic struct {
1104+
Method string `json:"method"`
1105+
Description string `json:"description,omitempty"`
1106+
}
1107+
1108+
type Notification interface {
1109+
Name() string
11001110
}
11011111

11021112
func (gm GetManifestMethod) Name() string {
@@ -1120,21 +1130,13 @@ func (gm GetManifestMethod) Call() (jrpc2.Result, error) {
11201130
}
11211131
}
11221132

1123-
m.Options = make([]Option, len(gm.plugin.options))
1124-
i := 0
1133+
m.Options = make([]Option, 0, len(gm.plugin.options))
11251134
for _, option := range gm.plugin.options {
1126-
m.Options[i] = option
1127-
i++
1128-
}
1129-
m.Subscriptions = make([]string, len(gm.plugin.subscriptions))
1130-
for i, sub := range gm.plugin.subscriptions {
1131-
m.Subscriptions[i] = sub
1132-
}
1133-
m.Hooks = make([]Hook, len(gm.plugin.hooks))
1134-
for i, hook := range gm.plugin.hooks {
1135-
m.Hooks[i] = hook
1135+
m.Options = append(m.Options, option)
11361136
}
11371137

1138+
m.Subscriptions = gm.plugin.subscriptions
1139+
m.Hooks = gm.plugin.hooks
11381140
m.Dynamic = gm.plugin.dynamic
11391141

11401142
if gm.plugin.features.AreSet() {
@@ -1144,6 +1146,7 @@ func (gm GetManifestMethod) Call() (jrpc2.Result, error) {
11441146
}
11451147
}
11461148
m.FeatureBits = gm.plugin.features
1149+
m.Notifications = gm.plugin.notifications
11471150

11481151
return m, nil
11491152
}
@@ -1317,6 +1320,7 @@ type Plugin struct {
13171320
stopped bool
13181321
dynamic bool
13191322
features *FeatureBits
1323+
notifications []NotificationTopic
13201324
}
13211325

13221326
func NewPlugin(initHandler func(p *Plugin, o map[string]Option, c *Config)) *Plugin {
@@ -1498,6 +1502,21 @@ func (p *Plugin) UnregisterOption(o Option) error {
14981502
return nil
14991503
}
15001504

1505+
func (p *Plugin) RegisterNotificationTopic(topic string, description string) {
1506+
p.notifications = append(p.notifications, NotificationTopic{
1507+
Method: topic,
1508+
Description: description,
1509+
})
1510+
}
1511+
1512+
func (p *Plugin) EmitCustomNotification(payload jrpc2.Method) error {
1513+
if err := p.server.Notify(payload); err != nil {
1514+
return fmt.Errorf("failed to emit notification for topic %s: %w", payload.Name(), err)
1515+
}
1516+
1517+
return nil
1518+
}
1519+
15011520
// this always returns a string option. left as is for legacy reasons
15021521
func (p *Plugin) GetOption(name string) (string, error) {
15031522
opt := p.options[name]
@@ -1557,60 +1576,60 @@ func (p *Plugin) getOptionSet() map[string]Option {
15571576
}
15581577

15591578
func (p *Plugin) SubscribeConnect(cb func(c *ConnectEvent)) {
1560-
p.subscribe(&ConnectEvent{
1579+
p.Subscribe(&ConnectEvent{
15611580
cb: cb,
15621581
})
15631582
}
15641583

15651584
func (p *Plugin) SubscribeDisconnect(cb func(c *DisconnectEvent)) {
1566-
p.subscribe(&DisconnectEvent{
1585+
p.Subscribe(&DisconnectEvent{
15671586
cb: cb,
15681587
})
15691588
}
15701589

15711590
func (p *Plugin) SubscribeInvoicePaid(cb func(c *Payment)) {
1572-
p.subscribe(&InvoicePaidEvent{
1591+
p.Subscribe(&InvoicePaidEvent{
15731592
cb: cb,
15741593
})
15751594
}
15761595

15771596
func (p *Plugin) SubscribeChannelOpened(cb func(c *ChannelOpened)) {
1578-
p.subscribe(&ChannelOpenedEvent{
1597+
p.Subscribe(&ChannelOpenedEvent{
15791598
cb: cb,
15801599
})
15811600
}
15821601

15831602
func (p *Plugin) SubscribeWarnings(cb func(c *Warning)) {
1584-
p.subscribe(&WarnEvent{
1603+
p.Subscribe(&WarnEvent{
15851604
cb: cb,
15861605
})
15871606
}
15881607

15891608
func (p *Plugin) SubscribeSendPaySuccess(cb func(c *SendPaySuccess)) {
1590-
p.subscribe(&SendPaySuccessEvent{
1609+
p.Subscribe(&SendPaySuccessEvent{
15911610
cb: cb,
15921611
})
15931612
}
15941613

15951614
func (p *Plugin) SubscribeSendPayFailure(cb func(c *SendPayFailure)) {
1596-
p.subscribe(&SendPayFailureEvent{
1615+
p.Subscribe(&SendPayFailureEvent{
15971616
cb: cb,
15981617
})
15991618
}
16001619

16011620
func (p *Plugin) SubscribeForwardings(cb func(c *Forwarding)) {
1602-
p.subscribe(&ForwardEvent{
1621+
p.Subscribe(&ForwardEvent{
16031622
cb: cb,
16041623
})
16051624
}
16061625

16071626
func (p *Plugin) SubscribeShutdown(cb func()) {
1608-
p.subscribe(&ShutdownEvent{
1627+
p.Subscribe(&ShutdownEvent{
16091628
cb: cb,
16101629
})
16111630
}
16121631

1613-
func (p *Plugin) subscribe(subscription jrpc2.ServerMethod) {
1632+
func (p *Plugin) Subscribe(subscription jrpc2.ServerMethod) {
16141633
p.server.Register(subscription)
16151634
p.subscriptions = append(p.subscriptions, subscription.Name())
16161635
}

glightning/plugin_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"io"
77
"log"
88
"os"
9+
"strings"
910
"sync"
1011
"testing"
1112
"time"
@@ -756,6 +757,65 @@ func TestSubscription_Disconnected(t *testing.T) {
756757
runTest(t, plugin, msg+"\n\n", "")
757758
}
758759

760+
type testCustomPayload struct {
761+
Message string `json:"message"`
762+
Code int `json:"code"`
763+
}
764+
765+
type testCustomEvent struct {
766+
Payload testCustomPayload `json:"custom-topic"`
767+
cb func(payload *testCustomPayload)
768+
}
769+
770+
func (e *testCustomEvent) Name() string {
771+
return "custom-topic"
772+
}
773+
774+
func (e *testCustomEvent) New() interface{} {
775+
return &testCustomEvent{cb: e.cb}
776+
}
777+
778+
func (e *testCustomEvent) Call() (jrpc2.Result, error) {
779+
e.cb(&e.Payload)
780+
return nil, nil
781+
}
782+
783+
func TestSubscription_CustomEventNotification(t *testing.T) {
784+
var wg sync.WaitGroup
785+
defer await(t, &wg)
786+
787+
wg.Add(1)
788+
initFn := getInitFunc(t, func(t *testing.T, options map[string]glightning.Option, config *glightning.Config) {
789+
t.Error("Should not have called init when calling get manifest")
790+
})
791+
792+
plugin := glightning.NewPlugin(initFn)
793+
794+
plugin.Subscribe(&testCustomEvent{
795+
cb: func(payload *testCustomPayload) {
796+
defer wg.Done()
797+
798+
assert.Equal(t, "Hello World", payload.Message)
799+
assert.Equal(t, 200, payload.Code)
800+
},
801+
})
802+
803+
msg := `{
804+
"jsonrpc":"2.0",
805+
"method":"custom-topic",
806+
"params":{
807+
"custom-topic":{
808+
"message":"Hello World",
809+
"code": 200
810+
}
811+
}
812+
}`
813+
814+
compactMsg := strings.ReplaceAll(strings.ReplaceAll(msg, "\n", ""), "\t", "")
815+
816+
runTest(t, plugin, compactMsg+"\n\n", "")
817+
}
818+
759819
func TestSubscription_Shutdown(t *testing.T) {
760820
var wg sync.WaitGroup
761821
defer await(t, &wg)

0 commit comments

Comments
 (0)