nip47

package
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Unlicense Imports: 13 Imported by: 0

Documentation

Overview

Package nip47 implements NIP-47: Nostr Wallet Connect (NWC), a protocol letting Nostr clients access a remote Lightning wallet service over end-to-end encrypted Nostr events, using a unique keypair per connection.

This package is the protocol layer only: building/parsing the info, request, response, and notification events, encryption negotiation (NIP-04 legacy vs NIP-44), the standard command set, and the nostr+walletconnect:// pairing URI. It has no opinion on how a wallet service persists connections, enforces budgets, or talks to a Lightning backend — that belongs to the consumer (e.g. a wallet-service application) built on top of this package.

Index

Constants

View Source
const (
	MethodPayInvoice        = "pay_invoice"
	MethodMultiPayInvoice   = "multi_pay_invoice"
	MethodPayKeysend        = "pay_keysend"
	MethodMultiPayKeysend   = "multi_pay_keysend"
	MethodMakeInvoice       = "make_invoice"
	MethodMakeHoldInvoice   = "make_hold_invoice"
	MethodCancelHoldInvoice = "cancel_hold_invoice"
	MethodSettleHoldInvoice = "settle_hold_invoice"
	MethodLookupInvoice     = "lookup_invoice"
	MethodListTransactions  = "list_transactions"
	MethodGetBalance        = "get_balance"
	MethodGetInfo           = "get_info"
	MethodSignMessage       = "sign_message"
	// MethodGetBudget is not defined by the NIP-47 spec text, but like
	// MethodMultiPayInvoice/MethodMultiPayKeysend/MethodSignMessage it is a
	// widely-implemented extension method (alongside get_info) dispatched
	// through the same request/response envelope as any spec method.
	MethodGetBudget = "get_budget"
)

Standard NIP-47 method names, used as the "method" field of a Request and the "result_type" field of its Response.

View Source
const (
	ErrRateLimited           = "RATE_LIMITED"
	ErrNotImplemented        = "NOT_IMPLEMENTED"
	ErrInsufficientBalance   = "INSUFFICIENT_BALANCE"
	ErrQuotaExceeded         = "QUOTA_EXCEEDED"
	ErrRestricted            = "RESTRICTED"
	ErrUnauthorized          = "UNAUTHORIZED"
	ErrInternal              = "INTERNAL"
	ErrUnsupportedEncryption = "UNSUPPORTED_ENCRYPTION"
	ErrOther                 = "OTHER"
	ErrPaymentFailed         = "PAYMENT_FAILED"
	ErrNotFound              = "NOT_FOUND"
	ErrExpired               = "EXPIRED"
	ErrBadRequest            = "BAD_REQUEST"
)

NIP-47 error codes, used as the "code" field of a Response's Error.

View Source
const (
	NotificationPaymentReceived     = "payment_received"
	NotificationPaymentSent         = "payment_sent"
	NotificationHoldInvoiceAccepted = "hold_invoice_accepted"
)

Notification type values, used as the "notification_type" field of a Notification.

View Source
const (
	KindNWCInfo               = 13194 // wallet service capability advertisement
	KindNWCRequest            = 23194 // client -> wallet service command
	KindNWCResponse           = 23195 // wallet service -> client result
	KindNWCLegacyNotification = 23196 // wallet service -> client event alert, NIP-04 encrypted
	KindNWCNotification       = 23197 // wallet service -> client event alert, NIP-44 encrypted
)

Event kinds defined by NIP-47.

View Source
const (
	EncryptionNIP04   = "nip04"
	EncryptionNIP44V2 = "nip44_v2"
)

Encryption scheme identifiers used in the info event's "encryption" tag and the request event's "encryption" tag.

View Source
const PairingURIScheme = "nostr+walletconnect"

PairingURIScheme is the URI scheme used by NIP-47 connection strings.

Variables

This section is empty.

Functions

func BuildPairingURI

func BuildPairingURI(walletPubkey string, relayURLs []string, secret string, extra url.Values) string

BuildPairingURI builds a nostr+walletconnect:// connection URI of the form "nostr+walletconnect://{pubkey}?relay={url}&relay={url2}&secret={hex}...", with one repeated "relay" param per entry in relayURLs. extra carries additional optional query parameters (e.g. "lud16"); pass nil if none are needed.

func NewErrorResponseEvent added in v0.2.2

func NewErrorResponseEvent(walletPrivKey, appPubkey, resultType string, respErr Error, requestEvent *nip01.Event, encryption string, extraTags ...[]string) (*nip01.Event, error)

NewErrorResponseEvent builds and encrypts an error kind:23195 response event answering requestEvent. Caller must sign it with walletPrivKey.

func NewInfoEvent added in v0.2.2

func NewInfoEvent(walletPubkey string, methods, notificationTypes, supportedEncryptions []string) *nip01.Event

NewInfoEvent builds an unsigned kind:13194 info event advertising the wallet service's capabilities. Caller must sign it with the wallet service identity key matching walletPubkey.

func NewNotificationEvent added in v0.2.2

func NewNotificationEvent(walletPrivKey, appPubkey string, notif Notification, useNIP44 bool) (*nip01.Event, error)

NewNotificationEvent builds and encrypts a notification event from the wallet service to the client: kind:23197 (NIP-44) if useNIP44 is true, otherwise the legacy kind:23196 (NIP-04). Caller must sign it with walletPrivKey.

func NewRequestEvent added in v0.2.2

func NewRequestEvent(appPrivKey, walletPubkey, method string, params any, encryption string) (*nip01.Event, error)

NewRequestEvent builds and encrypts a kind:23194 request event from the client's connection key to the wallet service. params is marshaled to JSON internally — pass a typed params struct (e.g. PayInvoiceParams), or nil for methods that take none (e.g. get_balance, get_info). encryption must be EncryptionNIP04 or EncryptionNIP44V2. Caller must sign it with appPrivKey.

func NewResponseEvent added in v0.2.2

func NewResponseEvent(walletPrivKey, appPubkey, resultType string, result any, requestEvent *nip01.Event, encryption string, extraTags ...[]string) (*nip01.Event, error)

NewResponseEvent builds and encrypts a successful kind:23195 response event answering requestEvent. result is marshaled to JSON internally — pass a typed result struct (e.g. PayInvoiceResult), or nil if the method has no result payload. For an error response, use NewErrorResponseEvent instead. encryption must be EncryptionNIP04 or EncryptionNIP44V2 (typically the scheme requestEvent itself used). extraTags is appended after the standard p/e/(encryption) tags — used to attach a ["d", subPaymentID] tag when building one of the per-sub-payment fanout response events multi_pay_invoice/multi_pay_keysend require (one call per sub-payment, not a single batched response). Caller must sign it with walletPrivKey.

Types

type CancelHoldInvoiceParams

type CancelHoldInvoiceParams struct {
	PaymentHash string `json:"payment_hash"`
}

CancelHoldInvoiceParams is the cancel_hold_invoice request payload.

type Error

type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

Error is a NIP-47 response error object.

type GetBalanceResult

type GetBalanceResult struct {
	BalanceMloki int64 `json:"balance"`
}

GetBalanceResult is the get_balance response payload.

type GetBudgetResult

type GetBudgetResult struct {
	UsedBudgetMloki  int64  `json:"used_budget"`
	TotalBudgetMloki int64  `json:"total_budget"`
	RenewsAt         *int64 `json:"renews_at,omitempty"`
	RenewalPeriod    string `json:"renewal_period"`
}

GetBudgetResult is the get_budget response payload. Like MethodGetBudget itself, this is an extension not defined by the NIP-47 spec text. It takes no params, like get_balance/get_info.

type GetInfoResult

type GetInfoResult struct {
	Alias         string   `json:"alias,omitempty"`
	Color         string   `json:"color,omitempty"`
	Pubkey        string   `json:"pubkey,omitempty"`
	Network       string   `json:"network,omitempty"`
	BlockHeight   int64    `json:"block_height,omitempty"`
	BlockHash     string   `json:"block_hash,omitempty"`
	Methods       []string `json:"methods"`
	Notifications []string `json:"notifications,omitempty"`
}

GetInfoResult is the get_info response payload.

type InfoEvent

type InfoEvent struct {
	*nip01.Event
	Methods              []string
	NotificationTypes    []string
	SupportedEncryptions []string
}

InfoEvent is the parsed kind:13194 wallet capability advertisement.

func ParseInfoEvent

func ParseInfoEvent(event *nip01.Event) (*InfoEvent, error)

ParseInfoEvent parses a kind:13194 info event. Absence of the encryption tag implies the wallet only supports legacy NIP-04, per spec.

type ListTransactionsParams

type ListTransactionsParams struct {
	From   *int64 `json:"from,omitempty"`
	Until  *int64 `json:"until,omitempty"`
	Limit  *int64 `json:"limit,omitempty"`
	Offset *int64 `json:"offset,omitempty"`
	Unpaid bool   `json:"unpaid,omitempty"`
	Type   string `json:"type,omitempty"`
}

ListTransactionsParams is the list_transactions request payload.

type ListTransactionsResult

type ListTransactionsResult struct {
	Transactions []Transaction `json:"transactions"`
}

ListTransactionsResult is the list_transactions response payload.

type LookupInvoiceParams

type LookupInvoiceParams struct {
	PaymentHash string `json:"payment_hash,omitempty"`
	Invoice     string `json:"invoice,omitempty"`
}

LookupInvoiceParams is the lookup_invoice request payload. Exactly one of PaymentHash or Invoice should be set.

type MakeHoldInvoiceParams

type MakeHoldInvoiceParams struct {
	Amount             int64  `json:"amount"`
	Description        string `json:"description,omitempty"`
	DescriptionHash    string `json:"description_hash,omitempty"`
	Expiry             *int64 `json:"expiry,omitempty"`
	PaymentHash        string `json:"payment_hash"`
	MinCltvExpiryDelta *int64 `json:"min_cltv_expiry_delta,omitempty"`
}

MakeHoldInvoiceParams is the make_hold_invoice request payload.

type MakeInvoiceParams

type MakeInvoiceParams struct {
	Amount          int64           `json:"amount"`
	Description     string          `json:"description,omitempty"`
	DescriptionHash string          `json:"description_hash,omitempty"`
	Expiry          *int64          `json:"expiry,omitempty"`
	Metadata        json.RawMessage `json:"metadata,omitempty"`
}

MakeInvoiceParams is the make_invoice request payload.

type MultiPayInvoiceItem

type MultiPayInvoiceItem struct {
	PayInvoiceParams
	Id string `json:"id,omitempty"`
}

MultiPayInvoiceItem is one sub-payment of a multi_pay_invoice request. multi_pay_invoice/multi_pay_keysend are extension methods observed in NWC implementations (Alby Hub and its derivatives) rather than defined by the NIP-47 spec text itself; each sub-payment gets its own response event, tagged with a "d" tag equal to the sub-payment's Id (see NewResponseEvent's extraTags parameter).

type MultiPayInvoiceParams

type MultiPayInvoiceParams struct {
	Invoices []MultiPayInvoiceItem `json:"invoices"`
}

MultiPayInvoiceParams is the multi_pay_invoice request payload.

type MultiPayKeysendItem

type MultiPayKeysendItem struct {
	PayKeysendParams
	Id string `json:"id,omitempty"`
}

MultiPayKeysendItem is one sub-payment of a multi_pay_keysend request.

type MultiPayKeysendParams

type MultiPayKeysendParams struct {
	Keysends []MultiPayKeysendItem `json:"keysends"`
}

MultiPayKeysendParams is the multi_pay_keysend request payload.

type Notification

type Notification struct {
	NotificationType string          `json:"notification_type"`
	Notification     json.RawMessage `json:"notification"`
}

Notification is the JSON shape of a decrypted notification event's content.

func ParseNotificationEvent

func ParseNotificationEvent(event *nip01.Event, appPrivKey string) (*Notification, error)

ParseNotificationEvent decrypts and parses a notification event (kind 23197 or legacy 23196) received by the client.

type PairingInfo

type PairingInfo struct {
	WalletPubkey string
	RelayURLs    []string
	Secret       string
	Extra        url.Values
}

PairingInfo is a parsed nostr+walletconnect:// connection URI.

func ParsePairingURI

func ParsePairingURI(uri string) (*PairingInfo, error)

ParsePairingURI parses a nostr+walletconnect:// connection URI.

type PayInvoiceParams

type PayInvoiceParams struct {
	Invoice  string          `json:"invoice"`
	Amount   *int64          `json:"amount,omitempty"`
	Metadata json.RawMessage `json:"metadata,omitempty"`
}

PayInvoiceParams is the pay_invoice request payload.

type PayInvoiceResult

type PayInvoiceResult struct {
	Preimage      string `json:"preimage"`
	FeesPaidMloki int64  `json:"fees_paid,omitempty"`
}

PayInvoiceResult is the pay_invoice response payload.

type PayKeysendParams

type PayKeysendParams struct {
	Amount     int64       `json:"amount"`
	Pubkey     string      `json:"pubkey"`
	Preimage   string      `json:"preimage,omitempty"`
	TLVRecords []TLVRecord `json:"tlv_records,omitempty"`
}

PayKeysendParams is the pay_keysend request payload.

type PayKeysendResult

type PayKeysendResult struct {
	Preimage      string `json:"preimage"`
	FeesPaidMloki int64  `json:"fees_paid,omitempty"`
}

PayKeysendResult is the pay_keysend response payload.

type Request

type Request struct {
	Method string          `json:"method"`
	Params json.RawMessage `json:"params,omitempty"`
}

Request is the JSON shape of a decrypted request event's content.

func ParseRequestEvent

func ParseRequestEvent(event *nip01.Event, walletPrivKey string) (*Request, error)

ParseRequestEvent decrypts and parses a kind:23194 request event received by the wallet service. The encryption scheme is determined by the presence/absence of the request's "encryption" tag, per spec.

type Response

type Response struct {
	ResultType string          `json:"result_type"`
	Error      *Error          `json:"error,omitempty"`
	Result     json.RawMessage `json:"result,omitempty"`
}

Response is the JSON shape of a decrypted response event's content.

type ResponseEvent

type ResponseEvent struct {
	*nip01.Event
	Response
	RequestEventID string // from the "e" tag
	SubPaymentID   string // from the "d" tag; empty for single-payment methods
}

ResponseEvent is a parsed kind:23195 response event.

func ParseResponseEvent

func ParseResponseEvent(event *nip01.Event, appPrivKey string) (*ResponseEvent, error)

ParseResponseEvent decrypts and parses a kind:23195 response event received by the client. The encryption scheme is determined by the presence/absence of the response's "encryption" tag.

type SettleHoldInvoiceParams

type SettleHoldInvoiceParams struct {
	Preimage string `json:"preimage"`
}

SettleHoldInvoiceParams is the settle_hold_invoice request payload.

type SignMessageParams

type SignMessageParams struct {
	Message string `json:"message"`
}

SignMessageParams is the sign_message request payload. Like multi_pay_invoice, sign_message is not defined by the NIP-47 spec text but is present in the reference info-event example and widely implemented.

type SignMessageResult

type SignMessageResult struct {
	Message   string `json:"message"`
	Signature string `json:"signature"`
}

SignMessageResult is the sign_message response payload.

type TLVRecord

type TLVRecord struct {
	Type  uint64 `json:"type"`
	Value string `json:"value"`
}

TLVRecord is a keysend custom TLV record.

type Transaction

type Transaction struct {
	Type            string          `json:"type"`
	State           string          `json:"state,omitempty"`
	Invoice         string          `json:"invoice,omitempty"`
	Description     string          `json:"description,omitempty"`
	DescriptionHash string          `json:"description_hash,omitempty"`
	Preimage        string          `json:"preimage,omitempty"`
	PaymentHash     string          `json:"payment_hash"`
	AmountMloki     int64           `json:"amount"`
	FeesPaidMloki   int64           `json:"fees_paid,omitempty"`
	CreatedAt       int64           `json:"created_at"`
	ExpiresAt       *int64          `json:"expires_at,omitempty"`
	SettledAt       *int64          `json:"settled_at,omitempty"`
	Metadata        json.RawMessage `json:"metadata,omitempty"`
}

Transaction is the standard NIP-47 transaction object shape: used in make_invoice/make_hold_invoice/lookup_invoice results, list_transactions result items, and payment_received/payment_sent notification payloads.

Directories

Path Synopsis
Package relayreg declares NIP-47 support to a relay engine.
Package relayreg declares NIP-47 support to a relay engine.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL