Manual Implementation of the UMA Auth Protocol
This guide will walk you through everything you need to do to implement the UMA Auth protocol manually
in your client application (without using the client SDKs).
The UMA Auth protocol uses a fairly standard OAuth 2.0 flow to establish connections between client
applications and their user's UMA-enabled wallets. You can implement this yourself, by paying special
attention to the following steps:
Request your user to specify their UMA address or the domain of the their UMA wallet (using some
UI component) that they wish to connect to your application.
Fetch the wallet's Configuration Document
from the
/.well-known/uma-configuration
path. For example, if your user's UMA address is
<username>@coolvasp.net
, you would make a GET
request to https://coolvasp.net/.well-known/uma-configuration
.
This is a JSON document which contains various OAuth related properties such as the authorization,
token and revocation endpoints, as well as NWC related properties such as supported NWC methods.Next, you'll begin implementing the OAuth exchange. To do this, you may choose to use a reputable
OAuth 2.0 library or implement it yourself. Make the OAuth authorization
request to the
authorization_endpoint
(from the configuration document) with the following query
parameters:- Standard OAuth Params:
- client_id: Your application's unique identifier, in the format
"appIdentityPubkey nostrRelayUrl"
whereappIdentityPubkey
is public key from your App Identity keypair and thenostrRelayUrl
is the url of the relay on which your App Registration event is published. For more information on how to generate these, see the App Identity Nostr Keys section. - redirect_uri: The URL in your app that will handle the OAuth callback from the wallet on successful authentication.
- response_type=code
- code_challenge: The PKCE code challenge.
- code_challenge_method=S256
- state: (optional) OAuth state param for csrf and state restoration.
- client_id: Your application's unique identifier, in the format
- NWC-related Params:
- required_commands: A space-separated list of commands that the app requires from the wallet. A connection will not be established if the wallet does not support all of these permissions, or if the user does not grant one of them.
- optional_commands: (optional) A space-separated list of commands that the wallet can enable to add additional functionality.
- budget: (optional) Requested budget in the format
<max_amount>.<currency>/<period>
. If the.<currency>
is omitted, satoshis are assumed. If/<period
is omitted, it’s a budget forever. For example, a budget string of“1000”
would mean that this connection can only ever be used for a maximum of 1000 satoshis sent.
Once the user has confirmed permissions for your client application in their wallet's UI, they will
be redirected back to the
redirect_uri
with an authorization code. You should handle this redirect
in your client application.Exchange the authorization code for the access token, full NWC connection, granted permissions,
spending limit, expiration info, etc by hitting the
token_endpoint
which is also specified in
the configuration document. You token request might look like this:POST /oauth/token HTTP/1.1
Host: https://umanwc.examplevasp.com
grant_type=authorization_code
&code=xxxxxxxxxxx
&redirect_uri=https://example-app.com/redirect
&code_verifier=Th7UHJdLswIYQxwSg29DbK1a_d9o41uNMTRmuH0PM8zyoMAQ
&client_id=npub16f80k0f4vg0nnlepxrqxeh81slyzst2d wss://myrelay.info
The
redirect_uri
and client_id
must match the values used in the authorization request. The
code_verifier
is the PKCE code verifier matching the code_challenge
used in the auth request.
If successful, the user's wallet will respond as follows:HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token":"b9d11fe05e266fe7389fdf1359211e7859656a7898d64f3066092156de109b31",
"token_type":"Bearer",
"expires_in":86400,
"refresh_token":"IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTDk",
"nwc_connection_uri": "nostr+walletconnect://a421a5e2a615eff3b797be5318e4e187d24b100748cfaa8d0b390ce659906d8f?relay=wss://relay.getalby.com/v1&secret=b9d11fe05e266fe7389fdf1359211e7859656a7898d64f3066092156de109b31&lud16=$bob@examplevasp.com"
"commands": ["get_budget", "pay_invoice", "fetch_quote", "make_invoice", "get_balance", "get_info", "pay_keysend", "lookup_user", "pay_to_address", "execute_quote"],
"budget": "100.USD/month",
"nwc_expires_at": 1721796505
}
You will now be able to use this NWC connection to make NWC requests to your user's wallet!
It is important to note that wallets will have relatively short TTLs for their access tokens.
You are also responsible for refreshing tokens when expired. To refresh tokens, you should
make a POST request to the same
token_endpoint
, this time specifying your refresh token
from your previous token response. Your refresh token request might look like this:POST /oauth/token HTTP/1.1
Host: https://umanwc.examplevasp.com
grant_type=refresh_token
&refresh_token=IwOGYzYTlmM2YxOTQ5MGE3YmNmMDFkNTVk
&client_id=npub16f80k0f4vg0nnlepxrqxeh81slyzst2d%20wss://myrelay.info
The wallet will respond with the same response format as the initial access token request.
Once your user has been throught the OAuth connection exchange, you can use the obtained NWC connection
and other metadata from the OAuth response to make requests to the UMA wallet:
- Choose a Nostr library or implement the protocol yourself using WebSockets. If you would like to use a library, you may refer to the "Making NWC Requests" section for recommendations.
- Establish a WebSocket connection using the NWC connection string, which can be found in the token
response
nwc_connection_uri
param. - Send and receive NWC messages over the WebSocket connection.
- Before you make an NWC request, you should ensure that your token is still valid, and if not, refresh your tokens.
- You should also check that the user has granted their wallet permission to execute the specific
NWC method that you wish to call by checking the granted permissions field
commands
in the OAuth response. - For a complete list of NWC methods in the UMA Auth protocol that you can call, see the protocol spec. This includes descriptions and the request and response format for each of the NWC methods. Note that support for these commands will also vary depending on what the user's wallet supports.