Nostr Wallet Connect, which NIP-47 defines: payments from the wallet of the listener, asked for over a relay of Nostr.
The listener gets a connection URI from the wallet. The URI holds a secret key, and whoever has it can spend from the wallet, so keep it as you keep a password, and show it to nobody. A connection hides the key, so a connection that's printed doesn't show it.
A command is data, a map of :method and :params. The content of each event is encrypted with NIP-44. The encryption of NIP-04, which NIP-47 keeps for old wallets, isn't written here, since NIP-04 has no check of a change, and its own text tells not to use it.
NIP-47 has the commands of invoices, and the command of keysend is in the extension NWC-04, in the repository nostr-wallet-connect/nwc. A wallet names the commands that it takes in its info event.
Nostr Wallet Connect, which NIP-47 defines: payments from the wallet of the listener, asked for over a relay of Nostr. The listener gets a connection URI from the wallet. The URI holds a secret key, and whoever has it can spend from the wallet, so keep it as you keep a password, and show it to nobody. A connection hides the key, so a connection that's printed doesn't show it. A command is data, a map of :method and :params. The content of each event is encrypted with NIP-44. The encryption of NIP-04, which NIP-47 keeps for old wallets, isn't written here, since NIP-04 has no check of a change, and its own text tells not to use it. NIP-47 has the commands of invoices, and the command of keysend is in the extension NWC-04, in the repository nostr-wallet-connect/nwc. A wallet names the commands that it takes in its info event.
(answer {:keys [wallet] :as connection} event)What the event of a wallet answers over connection, or a map with a
diagnostic under :error. The section Request and Response Events of
NIP-47 defines the event, of the kind 23195.
{:method "pay_invoice"
:request "5c83…" ; the id of the request that it answers
:preimage "0123…" :fees-msat 1000
:result {"preimage" "0123…" "fees_paid" 1000}}
The answer has the fields of the result in the keys of podcast-clj, and the :result as the wallet gave it. An amount is in millisatoshis, under :msat or :fees-msat, and a time is an instant.
An error of the wallet is :value/wallet-refused, with the :code of NIP-47 and the :message of the wallet. An event that isn't the signed event of the wallet for this connection is :value/wallet-unreadable. So is the result of a payment without a preimage, since a wallet gets the preimage when it pays.
The texts of an answer are as the wallet wrote them. Hiccup escapes them, but an app that writes HTML as text must escape them itself. This doesn't know the invoice of a payment, so it doesn't check the preimage.
What the `event` of a wallet answers over `connection`, or a map with a
diagnostic under :error. The section Request and Response Events of
NIP-47 defines the event, of the kind 23195.
{:method "pay_invoice"
:request "5c83…" ; the id of the request that it answers
:preimage "0123…" :fees-msat 1000
:result {"preimage" "0123…" "fees_paid" 1000}}
The answer has the fields of the result in the keys of podcast-clj, and
the :result as the wallet gave it. An amount is in millisatoshis, under
:msat or :fees-msat, and a time is an instant.
An error of the wallet is :value/wallet-refused, with the :code of
NIP-47 and the :message of the wallet. An event that isn't the signed
event of the wallet for this connection is :value/wallet-unreadable. So
is the result of a payment without a preimage, since a wallet gets the
preimage when it pays.
The texts of an answer are as the wallet wrote them. Hiccup escapes
them, but an app that writes HTML as text must escape them itself. This
doesn't know the invoice of a payment, so it doesn't check the
preimage.(ask! connection command)(ask! connection command opts)Ask the wallet of connection to do command with opts, and give its
answer, or a map with a diagnostic under :error. On the JVM it gives the
answer, and in ClojureScript a promise of it.
(ask! connection (pay-invoice "lnbc500n1…"))
;; => {:method "pay_invoice" :preimage "0123…" :proven? true …}
The answer to the payment of an invoice has :proven?. It's true when the preimage is the proof of the invoice. When it's false, the wallet says that it paid, and it gave no proof. Don't pay again then, since the wallet can have paid, and tell the listener, who knows the wallet. A keysend payment has no such proof, since the wallet of the sender makes its preimage.
The request goes to the first relay of the connection. The next relay gets it only when the event didn't leave the app, or when the relay refused the event. So the wallet gets a command once. The request expires after :timeout-seconds, and a wallet doesn't do a command that expired. A relay can give the wallet the same event again, and the expiry is the end of that too.
When the wallet gives no answer in time, the error is :value/wallet-silent. The request went out, so the wallet can do the command until :expires-at. Don't send a payment again before that time, and some time more, since the clocks of the app and the wallet differ. After it, a lookup of the invoice tells whether the wallet paid it.
A command with more bytes than a request holds gives :value/command-too-large, and no request goes out. A feed chooses the titles in the record of a payment, so a feed can make a command large.
The opts are these:
Ask the wallet of `connection` to do `command` with `opts`, and give its
answer, or a map with a diagnostic under :error. On the JVM it gives the
answer, and in ClojureScript a promise of it.
(ask! connection (pay-invoice "lnbc500n1…"))
;; => {:method "pay_invoice" :preimage "0123…" :proven? true …}
The answer to the payment of an invoice has :proven?. It's true when the
preimage is the proof of the invoice. When it's false, the wallet says
that it paid, and it gave no proof. Don't pay again then, since the
wallet can have paid, and tell the listener, who knows the wallet. A
keysend payment has no such proof, since the wallet of the sender makes
its preimage.
The request goes to the first relay of the connection. The next relay
gets it only when the event didn't leave the app, or when the relay
refused the event. So the wallet gets a command once. The request
expires after :timeout-seconds, and a wallet doesn't do a command that
expired. A relay can give the wallet the same event again, and the
expiry is the end of that too.
When the wallet gives no answer in time, the error is
:value/wallet-silent. The request went out, so the wallet can do the
command until :expires-at. Don't send a payment again before that time,
and some time more, since the clocks of the app and the wallet differ.
After it, a lookup of the invoice tells whether the wallet paid it.
A command with more bytes than a request holds gives
:value/command-too-large, and no request goes out. A feed chooses the
titles in the record of a payment, so a feed can make a command large.
The `opts` are these:
- :info, what the wallet tells of itself, fetched once for the
connection. Without it, this asks the relays for the info event
first. A wallet that doesn't take the command gives
:value/wallet-unsupported, and no request goes out.
- :timeout-seconds, in place of that of default-limits
- :send, a function that sends a request map to a relay, in place of
nostr/send!. Its response has :sent? true when the event of the
request went out. Without :sent?, the next relay gets the event.
- :allow-pred, a predicate of the URL of a relay. By default, nothing
goes to a private network. For a wallet on your own network, give
(constantly true).
- :now-fn, a function that gives the instant of now, the clock by default
- :random-fn, a function that gives a number of random bytes, from a
secure source by default(connection? x)Whether x is a connection. Its keys are in lower case, its wallet is a
point of the curve, and its secret is a secret key. Each of its relays
is the URL of a relay.
The secret is a hidden text. A plain text is a secret too, for an app that makes a connection of its own parts. But such a connection shows its secret when it's printed.
Whether `x` is a connection. Its keys are in lower case, its wallet is a point of the curve, and its secret is a secret key. Each of its relays is the URL of a relay. The secret is a hidden text. A plain text is a secret too, for an app that makes a connection of its own parts. But such a connection shows its secret when it's printed.
The limits of a request to a wallet that its options don't set.
A payment over Lightning can take a minute, so the wallet has :timeout-seconds to answer. The request of a command expires after that time.
The limits of a request to a wallet that its options don't set. A payment over Lightning can take a minute, so the wallet has :timeout-seconds to answer. The request of a command expires after that time.
(fetch-info! connection)(fetch-info! {:keys [wallet relays] :as connection} opts)Fetch what the wallet of connection tells of itself with opts. On
the JVM it gives the info, and in ClojureScript a promise of it.
A wallet gives its info event to its relays, and they keep it. When no relay has the event, the :error is :value/no-wallet-info, of the level info. When no relay answers, it's :value/wallet-unreachable.
The opts are those of ask!. Fetch the info once for each connection.
Fetch what the wallet of `connection` tells of itself with `opts`. On the JVM it gives the info, and in ClojureScript a promise of it. A wallet gives its info event to its relays, and they keep it. When no relay has the event, the :error is :value/no-wallet-info, of the level info. When no relay answers, it's :value/wallet-unreachable. The `opts` are those of ask!. Fetch the info once for each connection.
(format {:keys [wallet relays lud16] :as connection})The URI of Nostr Wallet Connect for connection, the text to store. It
has the secret of the connection, so keep it where you keep passwords.
The URI of Nostr Wallet Connect for `connection`, the text to store. It has the secret of the connection, so keep it where you keep passwords.
(get-balance)The command that asks the wallet for its balance.
The command that asks the wallet for its balance.
(get-info)The command that asks the wallet for its name, its network and the commands that it takes from this connection.
The command that asks the wallet for its name, its network and the commands that it takes from this connection.
(info event)What the info event of a wallet tells, as the section Info Event of
NIP-47 defines it:
{:methods ["pay_invoice" "get_balance"] ; the commands it takes
:encryption ["nip44_v2" "nip04"] ; the encryptions it reads
:extensions ["02" "04"]} ; its extensions of NWC
A wallet that names no encryption reads that of NIP-04 only, as the section Encryption of NIP-47 tells.
What the info `event` of a wallet tells, as the section Info Event of
NIP-47 defines it:
{:methods ["pay_invoice" "get_balance"] ; the commands it takes
:encryption ["nip44_v2" "nip04"] ; the encryptions it reads
:extensions ["02" "04"]} ; its extensions of NWC
A wallet that names no encryption reads that of NIP-04 only, as the
section Encryption of NIP-47 tells.(info-request {:keys [wallet] :as connection} url)The request that asks the relay at url for the info event of the
wallet of connection.
The request that asks the relay at `url` for the info event of the wallet of `connection`.
The kinds of the events of NIP-47, in its section Events: the info event of a wallet, the request of an app and the response of the wallet.
The kinds of the events of NIP-47, in its section Events: the info event of a wallet, the request of an app and the response of the wallet.
(lookup-invoice {:keys [invoice payment-hash] :as x})The command that asks the wallet for the state of the payment x, as
the section lookup_invoice of NIP-47 defines it. The x names the
payment by its :invoice or by its :payment-hash.
The command that asks the wallet for the state of the payment `x`, as the section lookup_invoice of NIP-47 defines it. The `x` names the payment by its :invoice or by its :payment-hash.
(make-invoice msat)(make-invoice msat
{:keys [description description-hash expiry metadata] :as opts})The command that makes an invoice for msat millisatoshis in the
wallet by opts, as the section make_invoice of NIP-47 defines it.
The opts can give :description, :description-hash, :expiry in
seconds, and :metadata.
The command that makes an invoice for `msat` millisatoshis in the wallet by `opts`, as the section make_invoice of NIP-47 defines it. The `opts` can give :description, :description-hash, :expiry in seconds, and :metadata.
(parse uri)The connection that the URI uri of Nostr Wallet Connect names, or nil
for a text that isn't such a URI.
{:wallet "b889…" ; the public key of the wallet service
:relays ["wss://relay.example"] ; where the wallet service listens
:secret #<secret> ; the secret key of the app, hidden
:lud16 "ann@example.org"} ; the Lightning address of the listener
The section Nostr Wallet Connect URI of NIP-47 defines the URI. It has the scheme nostr+walletconnect, one relay or more, and a secret. The relays are in a normal form, and a relay that isn't the URL of a relay is left out.
The secret is for this connection only. Whoever has it can spend from
the wallet, within the budget that the wallet gave the connection. It's
a hidden text of dk.simongray.wary-fetch.secret, which doesn't show in
a log or at a REPL. A printed connection doesn't read back, so store
the text of uri.
The URI is a claim of whoever wrote it. The :lud16 is where that person wants payments to go, so ask the listener before you use the address.
The connection that the URI `uri` of Nostr Wallet Connect names, or nil
for a text that isn't such a URI.
{:wallet "b889…" ; the public key of the wallet service
:relays ["wss://relay.example"] ; where the wallet service listens
:secret #<secret> ; the secret key of the app, hidden
:lud16 "ann@example.org"} ; the Lightning address of the listener
The section Nostr Wallet Connect URI of NIP-47 defines the URI. It has
the scheme nostr+walletconnect, one relay or more, and a secret. The
relays are in a normal form, and a relay that isn't the URL of a relay
is left out.
The secret is for this connection only. Whoever has it can spend from
the wallet, within the budget that the wallet gave the connection. It's
a hidden text of dk.simongray.wary-fetch.secret, which doesn't show in
a log or at a REPL. A printed connection doesn't read back, so store
the text of `uri`.
The URI is a claim of whoever wrote it. The :lud16 is where that person
wants payments to go, so ask the listener before you use the address.(pay-invoice invoice)(pay-invoice invoice {:keys [msat metadata] :as opts})The command that pays the BOLT 11 invoice by opts, as the section
pay_invoice of NIP-47 defines it. The opts are these:
The command that pays the BOLT 11 `invoice` by `opts`, as the section pay_invoice of NIP-47 defines it. The `opts` are these: - :msat, the amount for an invoice that names none - :metadata, a map that the wallet keeps with the payment. NWC-06 names keys of such metadata, such as "comment".
(pay-keysend payment {:keys [address] :as recipient})The command that pays payment to recipient with keysend, as NWC-04
defines it, or nil for a recipient that isn't a node or a payment
without an amount.
The payment is the map of dk.simongray.podcast.value, and the recipient is a recipient of a value block, of the type node. The command has the custom records of the payment: the bLIP-10 record, and the custom key and value of the recipient. The report of the command says when the records leave out the custom key or value. Don't send the command then.
The command that pays `payment` to `recipient` with keysend, as NWC-04 defines it, or nil for a recipient that isn't a node or a payment without an amount. The payment is the map of dk.simongray.podcast.value, and the recipient is a recipient of a value block, of the type node. The command has the custom records of the payment: the bLIP-10 record, and the custom key and value of the recipient. The report of the command says when the records leave out the custom key or value. Don't send the command then.
(public-key connection)The public key of the app in connection, by which the wallet knows
the connection. It's the public key of the secret of the connection.
The public key of the app in `connection`, by which the wallet knows the connection. It's the public key of the secret of the connection.
(request-event {:keys [wallet] :as connection}
{:keys [method params] :as command}
{:keys [at nonce aux expires-at] :as opts})The event that asks the wallet of connection to do command, made
from opts, or nil for a command with more bytes than a payload of
NIP-44 holds.
It's a signed event of the kind 23194, with the command in its content,
encrypted for the wallet. The section Request and Response Events of
NIP-47 defines it. The opts have what makes the event, since nothing
here reads a clock or makes random bytes:
Use new random bytes for each request.
The event that asks the wallet of `connection` to do `command`, made from `opts`, or nil for a command with more bytes than a payload of NIP-44 holds. It's a signed event of the kind 23194, with the command in its content, encrypted for the wallet. The section Request and Response Events of NIP-47 defines it. The `opts` have what makes the event, since nothing here reads a clock or makes random bytes: - :at, the instant of the request - :nonce, hexadecimal text of 32 bytes that nobody can guess, for the encryption - :aux, the same for the signature - :expires-at, the instant after which the wallet doesn't do the command, which is optional Use new random bytes for each request.
(unsupported info {:keys [method] :as command})Why the wallet with the info doesn't take command from podcast-clj,
as a map with a diagnostic under :error. It's nil when the wallet takes
the command, and when info is nil, since the wallet is unknown then.
The diagnostic is :value/wallet-unsupported. The wallet doesn't name the method of the command, or it doesn't read NIP-44 version 2.
Why the wallet with the `info` doesn't take `command` from podcast-clj, as a map with a diagnostic under :error. It's nil when the wallet takes the command, and when `info` is nil, since the wallet is unknown then. The diagnostic is :value/wallet-unsupported. The wallet doesn't name the method of the command, or it doesn't read NIP-44 version 2.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |