Wallet addresses are meant to be easy to remember or identify, unless your wallet provider chooses them for you. The address might include a long subdomain or even a random series of numbers and characters. But did you know that if you own a domain, you can set your wallet address to be the same as your domain?
So, instead of https://ilp.wallet.example/12345432/usd
, you can have $mywebsite.com
as your wallet address (well, technically, a payment pointer)! Itās as easy as pie to remember.
You can change your wallet without telling anyone about a new address. And not to forget the branding that comes with your domain - you can share it with people to request money with Open Payments, and itās handy when sending someone money as well. The Web Monetization extension also supports these custom wallet addresses.
I personally use $sidvishnoi.com
(which maps to my GateHub wallet). Feel free to send me money now that you remember the address!
Alright, so how do we get that address?
Set up custom payment pointer domain
Having a domain is a must-have for this to work. If you donāt own one, you can use a subdomain provided by your web hosting provider, but your own domain is better.
Iāll share a few approaches in this article, and later explain how these custom addresses relate to Web Monetization. The essential part in each approach is: you want https://{yourdomain.com}/.well-known/pay
to either redirect or rewrite to the wallet address you want to alias.
Configure in web host
If your web hosting provider allows custom URL redirects or rewrites, you can use this approach. Itās the easiest to maintain and set up, requiring no coding.
Cloudflare
For instance, letās consider Cloudflare. They have a concept of ārulesā that execute specific actions when a request (or URL) satisfies certain conditions. For simplicity, we will utilize what they refer to as a āpage ruleā.
- Access your website in the Cloudflare dashboard.
- Go to the Rules section in the sidebar and create a new Page rule.
- In the URL field, enter
{yourdomain.com}/.well-known/pay*
. - In settings, select āForwarding URLā with a 302 - Temporary Redirect.
- In the Destination URL field, write the wallet address your wallet provider gave and type
$1
at the end.- e.g., if your wallet address is
https://wallet.com/abc/zyz
, enterhttps://wallet.com/abc/xyz$1
. - The
$1
gets replaced by whatever content was there in place of*
:/.well-known/pay/jwks.json
will become/abc/xyz/jwks.json
;/.well-known/pay/
will become/abc/xyz/
.
- e.g., if your wallet address is
- Click Save Page Rule, and youāre ready!
Thereās a small catch, though. If there are tools that retrieve your payment pointer contents on the client side (for instance, Web Monetization Publisher tools), youāll need to ensure that your wallet address is set up to enable cross-origin requests, otherwise those tools may fail with a CORS error. No worries, we can easily add a new rule that lets any website access our wallet address directly from the client side.
- In the Rules section of Cloudflare dashboard, create a new Transform rule.
- Use anything in the Rule name, say, āEnable CORS for wallet addressā
- Choose a custom filter expression for the incoming request:
- Field: URI Path
- Operator: wildcard
- Value:
/.well-known/pay*
- Then, modify the response header:
- Header name:
Access-Control-Allow-Origin
- Value:
*
- Header name:
- Save. Now, this will enable CORS for your wallet address on any website.
NGINX
With a server using NGINX, the configuration is straightforward:
# nginx.conf
location ~ /.well-known/pay(.*) {
add_header Access-Control-Allow-Origin *; # enable cors
return 302 https://wallet.com/abc/xyz$1; # do a 302 redirect to original wallet address
}
You get the gist. Feel free to share solutions for your hosting providers in the comments!
_redirects
file
Some providers, especially those that host static websites, support a _redirects
file where you can create a mapping of URL redirects. Thereās also a companion _headers
file in some providers, which is particularly practical for enabling CORS support.
Static sites hosted on platforms like Netlify and Cloudflare can utilize this approach. It's important to ensure that the _redirects
and _headers
files are located in the top-level of your build directory. Depending on your static site generator, you may need to place these files in the "public" folder of your site's source code.
# _redirects
/.well-known/pay https://wallet.com/abc/xyz 302
/.well-known/pay/jwks.json https://wallet.com/abc/xyz/jwks.json 302
# _headers
/.well-known/pay*
Access-Control-Allow-Origin: *
Other providers like Surge, Vercel may have their own syntax for the redirects file.
Dynamic rewrite/redirect from website
If you have complete control over your websiteās routes, youāll get the best results. Instead of redirecting, you can use rewrites. This way, the people directly visiting your wallet address wonāt see the URL in the address bar change to your original wallet address. Iāll share a few examples.
Node.js / Express
const WALLET_ADDRESS = 'https://wallet.com/abc/xyz';
app.get('/.well-known/pay', (req, res) => {
const json = await fetch(WALLET_ADDRESS).then(r => r.json())
res.json(json)
})
app.options('/.well-known/pay', (req, res) => {
res.set('Access-Control-Allow-Origin', '*')
})
app.get('/.well-known/pay/jwks.json', (req, res) => {
res.redirect(302, `${WALLET_ADDRESS}/jwks.json`)
});
Cloudflare Workers
Even if you donāt host your entire website on Cloudflare, you can create a worker there (using your domain or subdomain), just for the custom wallet address.
const WALLET_ADDRESS = "https://wallet.com/abc/xyz";
export default {
async fetch(request) {
const url = new URL(req.url);
if (url.pathname === "/.well-known/pay") {
const json = await fetch(WALLET_ADDRESS).then(r => r.json());
return Response.json(json);
}
// ... handle other requests, or by default, return error
// return new Response('not found', { status: 404 })
},
};
Wordpress
While you can write some PHP code for this functionality, I would recommend using an existing plugin to manage redirects and rewrites. The redirection plugin can be a good option. Their docs should guide you well.
Static website
If you only have a static website and are stuck with a hosting provider that doesn't allow customizations like mentioned above (e.g., GitHub Pages), you can still have a custom payment pointer, but there might be some limitations.
You cannot have $mywebsite.com
, but $mywebsite.com/pay.json
may work. It might be better or worse than what your wallet provider gave you.
In case youāre wondering, no, the http-equiv
HTML meta tag based redirect wonāt work. The redirects have to be at HTTP-level.
- Grab the JSON response for your original wallet address.
- You can use online services like https://jsonviewer.stack.hu, or https://hoppscotch.io to view the JSON response, or use
curl
if youāre into those things. - Opening the wallet address URL directly in your browser may not show you the JSON response, as some wallets use it as a landing page for others to send you money.
- You can use online services like https://jsonviewer.stack.hu, or https://hoppscotch.io to view the JSON response, or use
- Create a
pay.json
file (or use any other name, it just needs to have the.json
extension), and paste in the above JSON. For example: - Deploy your static site!
# for example, with curl
$ curl -sSL -H 'Accept: application/json' 'https://ilp.gatehub.net/981946513/eur' > pay.json
$ cat pay.json
# {"id":"https://ilp.gatehub.net/981946513/eur","publicName":"981946513","assetCode":"EUR","assetScale":2,"authServer":"https://rafiki.gatehub.net","resourceServer":"https://ilp.gatehub.net"}
Note that, given the lack of control over headers, you may face CORS issues as explained above, but itāll work with most other Open Payment uses.
How does it work with Web Monetization
The <link>
element
A payment pointer, such as $mywebsite.com
, is convenient for many purposes. However, when you want to add your wallet address to your website as a Web Monetization receiver, you need to convert that payment pointer to the Open Payments "wallet address" format for use with the <link>
tag (why?). Slightly disappointing, but hey, you only need to do this once!
You can use the link tag generator to convert the payment pointer to a valid link tag.
If youāre using the same domain as your website, you can use the link elementās URL resolution by writing the <link>
tag like following:
<link rel="monetization" href="/.well-known/pay" />
Aside: During local development on localhost, if you have the Web Monetization browser extension installed and are using a CDN or host-level configuration, the extension won't resolve to your actual wallet address, and no real money will be sent during regular website development. And when you want to test Web Monetization integrations, you can resolve the URL to a different test wallet address!
Usage in extension
The Web Monetization browser extension allows you to use any payment pointer or wallet address to connect your wallet as a sender. This means using a custom, branded payment pointer works the same as using your wallet's address directly. So, feel free to use your branded payment pointer there as well!
Once youāve connected using your custom payment pointer, the extension will show you both the custom payment pointer and the corresponding original wallet address on the Settings screen.
Aside: The Web Monetization API doesnāt allow the websites to know what payment pointer/wallet address was used by the payer, so they cannot directly correlate the payments to your identity (your domain name). The websiteās wallet may display information about the sender, but itāll only show the original wallet address there, not your custom alias.
MonetizationEvent
Letās say, instead of using a wallet address that our provider gave us, we alias it to a custom address as shown above, and add it to our webpage. This sort of indirection can also arise from using the probabilistic revenue sharing generator, or from your wallet provider may be using an aliased wallet address itself.
When a monetization
event is emitted, how do we know what wallet address was actually used? And how do we know what wallet address we originally provided? This is even more relevant if your webpage includes multiple monetization link tags.
Thankfully, the MonetizationEvent
includes both these details!
Letās look at the MonetizationEvent
in detail.
interface MonetizationEvent : Event {
readonly attribute MonetizationCurrencyAmount amountSent;
readonly attribute USVString paymentPointer;
readonly attribute USVString? incomingPayment;
// other details not relevant in this context
}
Here, paymentPointer
is the resolved wallet address that was used. For example, with a custom domain payment pointer - like Iāve mapped $sidvishnoi.com
to resolve to my GateHub wallet address (https://ilp.gatehub.net/981946513/eur
) above - the paymentPointer
will resolve to my GateHub address. When using a wallet address from the probabilistic revenue sharing tool, itāll correspond to the wallet address that was chosen randomly.
And how do we get the original wallet address?
If you look closely, the MonetizationEvent
inherits the Event
interface. So, everything that belongs to Event
is also part of MonetizationEvent
. The part weāre looking for here is the eventās target
attribute. This target corresponds to the <link rel=āmonetizationā>
element where you added your wallet address. The link element has the href
attribute, which corresponds to the original wallet address we provided on our page. We can get the original wallet address as follows:
<html>
<head>
<link rel="monetization" href="https://sidvishnoi.com/.well-known/pay" />
</head>
</html>
window.addEventListener('monetization', event => {
const linkElement: HTMLLinkElement = event.target;
const originalWalletAddress = linkElement.href;
// -> https://sidvishnoi.com/.well-known/pay
const usedWalletAddress = event.paymentPointer;
// -> https://ilp.gatehub.net/981946513/eur
});
Depending on the use case, you may care about either or both of the wallet addresses. I hope it was helpful for you to know how to get each.
Closing words
I look forward to seeing wallet addresses on your own domains! Remember, $sidvishnoi.com
is my payment pointer š
Top comments (0)