Add wallet service implementation and mock CLI tool

- pkg/protocol/nwc/wallet.go
  - Implemented `WalletService` with method registration and request handling.
  - Added default stub handlers for supported wallet methods.
  - Included support for notifications with `SendNotification`.

- pkg/protocol/nwc/client-methods.go
  - Added `Subscribe` function for handling client subscriptions.

- cmd/walletcli/mock-wallet-service/main.go
  - Implemented a mock CLI tool for wallet service.
  - Added command-line flags for relay connection and key management.
  - Added handlers for various wallet service methods (e.g., `GetInfo`, `GetBalance`, etc.).

- pkg/protocol/nwc/types.go
  - Added `GetWalletServiceInfo` to the list of wallet service capabilities.
This commit is contained in:
2025-08-08 17:34:44 +01:00
parent bb8f070992
commit e94d68c3b2
8 changed files with 2010 additions and 189 deletions

View File

@@ -106,8 +106,59 @@ func handleGetWalletServiceInfo(c context.T, cl *nwc.Client) {
}
}
func handleGetInfo(c context.T, cl *nwc.Client) {
if _, raw, err := cl.GetInfo(c, true); !chk.E(err) {
func handleCancelHoldInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> cancel_hold_invoice <payment_hash>")
return
}
params := &nwc.CancelHoldInvoiceParams{
PaymentHash: args[0],
}
var err error
var raw []byte
if raw, err = cl.CancelHoldInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handleCreateConnection(c context.T, cl *nwc.Client, args []string) {
if len(args) < 3 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> create_connection <pubkey> <name> <methods> [<notification_types>] [<max_amount>] [<budget_renewal>] [<expires_at>]")
return
}
params := &nwc.CreateConnectionParams{
Pubkey: args[0],
Name: args[1],
RequestMethods: strings.Split(args[2], ","),
}
if len(args) > 3 {
params.NotificationTypes = strings.Split(args[3], ",")
}
if len(args) > 4 {
maxAmount, err := strconv.ParseUint(args[4], 10, 64)
if err != nil {
fmt.Printf("Error parsing max_amount: %v\n", err)
return
}
params.MaxAmount = &maxAmount
}
if len(args) > 5 {
params.BudgetRenewal = &args[5]
}
if len(args) > 6 {
expiresAt, err := strconv.ParseInt(args[6], 10, 64)
if err != nil {
fmt.Printf("Error parsing expires_at: %v\n", err)
return
}
params.ExpiresAt = &expiresAt
}
var raw []byte
var err error
if raw, err = cl.CreateConnection(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
@@ -124,86 +175,8 @@ func handleGetBudget(c context.T, cl *nwc.Client) {
}
}
func handleMakeInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> make_invoice <amount> [<description>] [<description_hash>] [<expiry>]")
return
}
amount, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
fmt.Printf("Error parsing amount: %v\n", err)
return
}
params := &nwc.MakeInvoiceParams{
Amount: amount,
}
if len(args) > 1 {
params.Description = args[1]
}
if len(args) > 2 {
params.DescriptionHash = args[2]
}
if len(args) > 3 {
expiry, err := strconv.ParseInt(args[3], 10, 64)
if err != nil {
fmt.Printf("Error parsing expiry: %v\n", err)
return
}
params.Expiry = &expiry
}
var raw []byte
if _, raw, err = cl.MakeInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handlePayInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> pay_invoice <invoice> [<amount>] [<comment>]")
return
}
params := &nwc.PayInvoiceParams{
Invoice: args[0],
}
if len(args) > 1 {
amount, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
fmt.Printf("Error parsing amount: %v\n", err)
return
}
params.Amount = &amount
}
if len(args) > 2 {
comment := args[2]
params.Metadata = &nwc.PayInvoiceMetadata{
Comment: &comment,
}
}
if _, raw, err := cl.PayInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handleLookupInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> lookup_invoice <payment_hash or invoice>")
return
}
params := &nwc.LookupInvoiceParams{}
// Determine if the argument is a payment hash or an invoice
if strings.HasPrefix(args[0], "ln") {
invoice := args[0]
params.Invoice = &invoice
} else {
paymentHash := args[0]
params.PaymentHash = &paymentHash
}
var err error
var raw []byte
if _, raw, err = cl.LookupInvoice(c, params, true); !chk.E(err) {
func handleGetInfo(c context.T, cl *nwc.Client) {
if _, raw, err := cl.GetInfo(c, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
@@ -251,6 +224,28 @@ func handleListTransactions(c context.T, cl *nwc.Client, args []string) {
}
}
func handleLookupInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> lookup_invoice <payment_hash or invoice>")
return
}
params := &nwc.LookupInvoiceParams{}
// Determine if the argument is a payment hash or an invoice
if strings.HasPrefix(args[0], "ln") {
invoice := args[0]
params.Invoice = &invoice
} else {
paymentHash := args[0]
params.PaymentHash = &paymentHash
}
var err error
var raw []byte
if _, raw, err = cl.LookupInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handleMakeHoldInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 2 {
fmt.Println("Error: Missing required arguments")
@@ -286,52 +281,36 @@ func handleMakeHoldInvoice(c context.T, cl *nwc.Client, args []string) {
}
}
func handleSettleHoldInvoice(c context.T, cl *nwc.Client, args []string) {
func handleMakeInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> settle_hold_invoice <preimage>")
fmt.Println("Usage: walletcli <NWC connection URL> make_invoice <amount> [<description>] [<description_hash>] [<expiry>]")
return
}
params := &nwc.SettleHoldInvoiceParams{
Preimage: args[0],
}
var raw []byte
var err error
if raw, err = cl.SettleHoldInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handleCancelHoldInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> cancel_hold_invoice <payment_hash>")
amount, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
fmt.Printf("Error parsing amount: %v\n", err)
return
}
params := &nwc.CancelHoldInvoiceParams{
PaymentHash: args[0],
params := &nwc.MakeInvoiceParams{
Amount: amount,
}
var err error
var raw []byte
if raw, err = cl.CancelHoldInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
if len(args) > 1 {
params.Description = args[1]
}
}
func handleSignMessage(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> sign_message <message>")
return
if len(args) > 2 {
params.DescriptionHash = args[2]
}
params := &nwc.SignMessageParams{
Message: args[0],
if len(args) > 3 {
expiry, err := strconv.ParseInt(args[3], 10, 64)
if err != nil {
fmt.Printf("Error parsing expiry: %v\n", err)
return
}
params.Expiry = &expiry
}
var raw []byte
var err error
if _, raw, err = cl.SignMessage(c, params, true); !chk.E(err) {
if _, raw, err = cl.MakeInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
@@ -381,42 +360,63 @@ func handlePayKeysend(c context.T, cl *nwc.Client, args []string) {
}
}
func handleCreateConnection(c context.T, cl *nwc.Client, args []string) {
if len(args) < 3 {
func handlePayInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> create_connection <pubkey> <name> <methods> [<notification_types>] [<max_amount>] [<budget_renewal>] [<expires_at>]")
fmt.Println("Usage: walletcli <NWC connection URL> pay_invoice <invoice> [<amount>] [<comment>]")
return
}
params := &nwc.CreateConnectionParams{
Pubkey: args[0],
Name: args[1],
RequestMethods: strings.Split(args[2], ","),
params := &nwc.PayInvoiceParams{
Invoice: args[0],
}
if len(args) > 3 {
params.NotificationTypes = strings.Split(args[3], ",")
}
if len(args) > 4 {
maxAmount, err := strconv.ParseUint(args[4], 10, 64)
if len(args) > 1 {
amount, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
fmt.Printf("Error parsing max_amount: %v\n", err)
fmt.Printf("Error parsing amount: %v\n", err)
return
}
params.MaxAmount = &maxAmount
params.Amount = &amount
}
if len(args) > 5 {
params.BudgetRenewal = &args[5]
}
if len(args) > 6 {
expiresAt, err := strconv.ParseInt(args[6], 10, 64)
if err != nil {
fmt.Printf("Error parsing expires_at: %v\n", err)
return
if len(args) > 2 {
comment := args[2]
params.Metadata = &nwc.PayInvoiceMetadata{
Comment: &comment,
}
params.ExpiresAt = &expiresAt
}
if _, raw, err := cl.PayInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handleSettleHoldInvoice(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> settle_hold_invoice <preimage>")
return
}
params := &nwc.SettleHoldInvoiceParams{
Preimage: args[0],
}
var raw []byte
var err error
if raw, err = cl.CreateConnection(c, params, true); !chk.E(err) {
if raw, err = cl.SettleHoldInvoice(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}
func handleSignMessage(c context.T, cl *nwc.Client, args []string) {
if len(args) < 1 {
fmt.Println("Error: Missing required arguments")
fmt.Println("Usage: walletcli <NWC connection URL> sign_message <message>")
return
}
params := &nwc.SignMessageParams{
Message: args[0],
}
var raw []byte
var err error
if _, raw, err = cl.SignMessage(c, params, true); !chk.E(err) {
fmt.Println(string(raw))
}
}