All this process has been a great learning for me and that's why I decided to document it. Connecting your node isn't (yet) that intuitive as it should, to auto withdraw your sats and use SN in a fully noncustodial manner. Consider this just a reference, it's generic due to my current tech skills did not enable me to cover all scenarios, so many things will not exactly match your case as it will be mostly depending on your node OS implementation. However, hope you'll find the following steps useful.


0. Open a channel with SN node

This is not mandatory, but it will definitely help the autowithdraws to find a cheaper and faster path toward your node.
03cc1d0932bb99b0697f5b5e5961b83ab7fd66f1efc4c9f5c7bad66c1bcbe78f02@52.5.194.83:9735
connect anonymously via Tor
03cc1d0932bb99b0697f5b5e5961b83ab7fd66f1efc4c9f5c7bad66c1bcbe78f02@xhlmkj7mfrl6ejnczfwl2vqik3xim6wzmurc2vlyfoqw2sasaocgpuad.onion:9735
via terminal:
lightning-cli connect <node_id> <ip> [<port>] lightning-cli fundchannel <node_id> <amount_in_satoshis>
It could also be a private channel and this will allow you to use it exclusively for your autowithdraws and get the cheapest and faster transaction ever setting Base Fee (mSats) and Fee Rate (mSats) equal to zero. By command line should be something like (depending on which node OS you are running):
lightning-cli setchannel <channel_id> <base_fee_millisatoshi> <fee_per_millionth>
<base_fee_millisatoshi>: This is a fixed amount of satoshis that will be charged for every payment routed through your channel, regardless of the payment's size.
<fee_per_millionth>: This is a variable fee represented in millionths of a satoshi per satoshi routed, essentially a percentage of the transaction amount.
... or you could also easily use Ride The Lightning in case you have it installed:

1. Get your rest host and port

SN supports both connections types, tor or clearnet. I highly suggest tor as it provides much more privacy and does not leak your node's IP, as SN is missing a warrant canary and does not yet issue any transparency report, stating that it had not received any national security letters or legal notice to disclose user data.

2. Get your invoice only rune

A rune is a base64 string with a unique id which can be used to access commands on your node. It's important to limit the commands the rune we'll use to only allow method=invoice.
So it's now time to open the terminal in your device and connect to your node via ssh, usually something like ssh user@node.local, and then run the following command to generate one:
lightning-cli createrune restrictions='["method=invoice"]'
It's useful to verify the rune has been correctly created, verifying the list of existing rune running the following command:
lightning-cli showrunes
You can see all official documentation about lightning-commando-rune from here.

3. Get your cert

The certificate is located inside your node and is easily accessible via CLI via terminal with the following command:
sudo nano ~/core-lightning/data/c-lightning-rest/certs/certificate.pem
Make sure the path is correct, and, if it's, you should get a new window with the certificate. This certificate is encoded with base64, copy it and make sure you remove all spaces before pasting it to the SN form.

4. Set your desired balance

Last values to set are the desired balance to be left on SN wallet and the maximum fee as a percent of the withdrawal amount. I assume that if a channel is set toward SN node (as explained in step 0) we can also set zero here. I decided to set 1 just in case. I also set zero on desired balance because I do not want SN to be a wallet, but just an app I use to share and learn.

5. Attach and troubleshoot

Hitting the attach button will submit the information attached in the form. When using Tor, it could take a bit, so be patient and wait for the outcome to appear in the log section below. In my case, still have unsuccessfully completed the goal, so my CLN node is not yet attached due to an error:
21m [cln] ERROR could not connect to CLN: request to https://hidden.onion:2104/v1/invoice failed, reason: write EPROTO C077EC2F067F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354: 21m [cln] ERROR failed to attach wallet
I'm not sure if I am doing something wrong, or if the Tor connection is maybe so unstable that give me this error... Anyway, ideally, I'm still waiting for @k00b and @ek to confirm what's going on from @SN side. If you have a CLN node and want to play around, head to wallet > attach wallets > CLN and try to connect your node.
It will be nice if you can comment below your experience attaching your CLN node, either via clearnet or tor, so it might help better understand and learn how to correctly achieve this goal!
Thanks for the write up. Super helpful!
This looks like an ssl version mismatch. I think @ek was discussing this on github before. We should be able to get this fixed once he comes online.
reply
Glad it helps, hopefully more people will be incentivized to connect their own nodes and remove some liability from SN!
Any plan for a warrant canary page?
reply
Yes, we've been discussing adding a canary icon to the footer that will turn into a dead canary if I don't post a signed message to an API endpoint once per month or something.
reply
Just be sure not to automate it ;)
reply
That will be super cool! Thanks
reply
i have tried to attach wallets over tor and come up with the same failed to attach wallet issue. havent tried CLN yet but will soon.
Hey, thanks for the guide! Formatting looks great, just unfortunate that the connection failed, lol
Regarding the error:
request to https://hidden.onion:2104/v1/invoice failed, reason: write EPROTO C077EC2F067F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354:
I've seen this error multiple times in the past. Unfortunately, I don't remember how I fixed it but after some research that also mentions this, I think I remember: it's when the response is HTTP not HTTPS which confuses openssl (good error messages are hard).
So just to be sure, are you sure you are running CLNRest over HTTPS not HTTP? But I guess the error could also happen under a lot of different circumstances, this might just be the most common cause.
Another thing I noticed is that you looked at a file named certificate.pem in a directory dedicated to the CLNRest plugin. Which CLN version are you running? It seems like you are not running at least v23.08 since CLNRest is a built-in plugin from this version on. It then stores the certificates at $HOME/.lightning/mainnet/.1
If you tell me which version you are running, I can check compatibility or if you might used a wrong certificate. certificate.pem is ambiguous since there should also be a server certificate in the same directory. In v23.08, the certificate we need is called ca.pem. It's the certificate of the certificate authority (CA) which establishes the trust chain, commonly called root certificate (yes, SSL/TLS is confusing).
Also, how did you encode the certificate? It might be already stored as base64 or hex in your version, but in v23.08, I have to run xxd -p -c0 ca.pem to get it in hex. My CA certificate starts with -----BEGIN CERTIFICATE----- which means it's not base64 or hex. Is this not the case for yours?
Footnotes
  1. That your node uses "c-lightning" is also an indicator for an old version since they call themselves core lightning now โ†ฉ
reply
Thanks @ek for your response and for sharing your insights.
Regarding the CLN version, I'm running 23.08-hotfix-1 so it should have CLNRest as built-in. And here's the path ~/core-lightning/data/c-lightning-rest/ to the certificate.pem 1. Also tried to find the ca.pem you mention without success, the only files found in the same folder are access.macaroon, certificate.pem, key.pem and rootKey.key. Any other place I could look for this file?
So I open the certificate and place the content between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- making sure I removed any space between the characters, converted to base64 using an online converter and then inputting in the form everything as a single line.
Anyhow, I think the error is on the first thing you're mentioning, about the SSL. My node run exclusively on Tor and does not use SSL certificate for the connection. When I try to append http:// to the onion address, the input validation script obviously give me error instantly: so are you saying I should run CLNRest over HTTPS? How I can do that?
Footnotes
  1. You can see I also mentioned in point 3. Get your cert โ†ฉ
reply
Anyhow, I think the error is on the first thing you're mentioning, about the SSL. My node run exclusively on Tor and does not use SSL certificate for the connection.
If you don't use SSL, you don't need to give us a certificate. We only use HTTPS with Tor if you give us a certificate. Else we'll try to connect to your node over HTTP for Tor then.
So maybe it will work if you simply leave out the certificate?
So are you saying I should run CLNRest over HTTPS? How I can do that?
No, you don't have to but you could. I assumed you would run it over HTTPS since it's the default of CLNRest:
--clnrest-protocol: Specifies the REST server protocol. Default is HTTPS.
reply
Yes I tried as well leaving the cert empty and I get a different error:
1s [cln] ERROR could not connect to CLN: invalid json response body at http://hidden.onion:2104/v1/invoice reason: Unexpected token < in JSON at position 0 1s [cln] ERROR failed to attach wallet
In the JSON I've multiple runes and the one in position 0 does not have any restriction (and is there by default). The rune I've created and using is in position 1 and has the correct restrictions:
{ "rune": "hidden", "unique_id": "1", "restrictions": [ { "alternatives": [ { "fieldname": "method", "value": "invoice", "condition": "=", "english": "method equal to invoice" } ], "english": "method equal to invoice" } ], "restrictions_as_english": "method equal to invoice" }
So is maybe SN script looking at the rune in position 0 only and giving back that error? Should I edit the JSON and switch rune positions? Or what else could I try?
reply
21 sats \ 8 replies \ @ek 21 May
Your rune seems to be fine. We only try to connect when we verified that your rune is properly limited to method=invoice. We then use this rune with the Rune header as mentioned here and as you can see here. We don't do anything else to it.
The error invalid json response body at http://hidden.onion:2104/v1/invoice reason: Unexpected token < in JSON at position 0 means that we connected to your node successfully but it didn't return JSON as expected.
Do you get a valid JSON response when you do a request from the same machine with cURL? Try this:
$ curl -X POST http://localhost:2104/v1/invoice -H "Rune: <your_rune_here>"
reply
maybe worth to mention I'm using umbrel
reply
I get the following error:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Error</title> </head> <body> <pre>Cannot POST /v1/invoice</pre> </body> </html>
reply
31 sats \ 5 replies \ @ek 21 May
๐Ÿคจ
Something seems to be wrong with your node. Looks like CLNRest is not running? I am not familiar with Umbrel unfortunately. Looking at the Umbrel docker-compose config for CLN, I wonder why they run CLNRest separately. Maybe that's related?
Since v23.08, it's built-in so they should add --clnrest-port during start to enable it which they don't.
reply
It is maybe using a different port?
Does make sense to edit the docker-compose.yml file and add under command: for example:
--clnrest-port=${APP_CORE_LIGHTNING_DAEMON_IP}: 2104
It then stores the certificates at $HOME/.lightning/mainnet/
It might use "bitcoin" instead of "mainnet"
reply
Thanks! Great and beautiful post!
Also very helpful. Will try it out.
reply
I'm glad, let us know if you get any error or if you successfully connect the node!
reply
Great guide. Thanks for sharing.
reply
๐Ÿค™
reply