Send via CLNRest (#2475)
* Send via CLNRest * Add cURL script to send payments using CLNRest * Serve CLNRest over HTTP in dev Upgrade to 24.11 fixed CORS issue * Update cln.md
This commit is contained in:
parent
a794b59b91
commit
de463e1f99
@ -55,6 +55,12 @@ const typeDefs = gql`
|
||||
apiKey: VaultEntryInput!
|
||||
): WalletSendBlink!
|
||||
|
||||
upsertWalletSendCLNRest(
|
||||
${shared},
|
||||
socket: String!,
|
||||
rune: VaultEntryInput!,
|
||||
): WalletSendCLNRest!
|
||||
|
||||
upsertWalletRecvBlink(
|
||||
${shared},
|
||||
currency: String!,
|
||||
@ -212,6 +218,7 @@ const typeDefs = gql`
|
||||
| WalletSendBlink
|
||||
| WalletSendWebLN
|
||||
| WalletSendLNC
|
||||
| WalletSendCLNRest
|
||||
| WalletRecvNWC
|
||||
| WalletRecvLNbits
|
||||
| WalletRecvPhoenixd
|
||||
@ -273,6 +280,12 @@ const typeDefs = gql`
|
||||
serverHost: VaultEntry!
|
||||
}
|
||||
|
||||
type WalletSendCLNRest {
|
||||
id: ID!
|
||||
socket: String!
|
||||
rune: VaultEntry!
|
||||
}
|
||||
|
||||
type WalletRecvNWC {
|
||||
id: ID!
|
||||
url: String!
|
||||
|
@ -530,8 +530,9 @@ services:
|
||||
- '--bitcoin-rpcuser=${RPC_USER}'
|
||||
- '--bitcoin-rpcpassword=${RPC_PASS}'
|
||||
- '--large-channels'
|
||||
- '--rest-port=3010'
|
||||
- '--rest-host=0.0.0.0'
|
||||
- '--clnrest-port=3010'
|
||||
- '--clnrest-host=0.0.0.0'
|
||||
- '--clnrest-protocol=http'
|
||||
expose:
|
||||
- "9735"
|
||||
ports:
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM polarlightning/clightning:23.08
|
||||
FROM polarlightning/clightning:24.11
|
||||
|
||||
RUN apt-get update -y \
|
||||
&& apt-get install -y jq wget \
|
||||
|
50
lib/cln.js
50
lib/cln.js
@ -1,8 +1,8 @@
|
||||
import fetch from 'cross-fetch'
|
||||
import crossFetch from 'cross-fetch'
|
||||
import crypto from 'crypto'
|
||||
import { getAgent } from '@/lib/proxy'
|
||||
import { assertContentTypeJson, assertResponseOk } from './url'
|
||||
import { FetchTimeoutError } from './fetch'
|
||||
import { fetchWithTimeout, FetchTimeoutError } from './fetch'
|
||||
import { WALLET_CREATE_INVOICE_TIMEOUT_MS } from './constants'
|
||||
|
||||
export const createInvoice = async ({ msats, description, expiry }, { socket, rune, cert }, { signal }) => {
|
||||
@ -13,15 +13,9 @@ export const createInvoice = async ({ msats, description, expiry }, { socket, ru
|
||||
const method = 'POST'
|
||||
let res
|
||||
try {
|
||||
res = await fetch(url, {
|
||||
res = await crossFetch(url, {
|
||||
method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Rune: rune,
|
||||
// can be any node id, only required for CLN v23.08 and below
|
||||
// see https://docs.corelightning.org/docs/rest#server
|
||||
nodeId: '02cb2e2d5a6c5b17fa67b1a883e2973c82e328fb9bd08b2b156a9e23820c87a490'
|
||||
},
|
||||
headers: headers(rune),
|
||||
agent,
|
||||
body: JSON.stringify({
|
||||
// CLN requires a unique label for every invoice
|
||||
@ -52,6 +46,42 @@ export const createInvoice = async ({ msats, description, expiry }, { socket, ru
|
||||
return inv
|
||||
}
|
||||
|
||||
export const sendPayment = async (bolt11, { socket, rune }, { signal }) => {
|
||||
// XXX we don't ask for the CA certificate because the browser's fetch API doesn't support http agents to override it.
|
||||
// Therefore, CLNRest send will only work with common CA certificates.
|
||||
|
||||
// API documentation
|
||||
// https://docs.corelightning.org/reference/pay
|
||||
const url = new URL(
|
||||
'/v1/pay',
|
||||
process.env.NODE_ENV === 'development' ? `http://${socket}` : `https://${socket}`)
|
||||
const method = 'POST'
|
||||
const res = await fetchWithTimeout(url, {
|
||||
method,
|
||||
headers: headers(rune),
|
||||
body: JSON.stringify({ bolt11 }),
|
||||
signal
|
||||
})
|
||||
assertResponseOk(res, { method })
|
||||
assertContentTypeJson(res, { method })
|
||||
|
||||
const result = await res.json()
|
||||
if (result.error) {
|
||||
throw new Error(result.error.message)
|
||||
}
|
||||
return result.payment_preimage
|
||||
}
|
||||
|
||||
function headers (rune) {
|
||||
const headers = new Headers()
|
||||
headers.append('Content-Type', 'application/json')
|
||||
headers.append('Rune', rune)
|
||||
// can be any node id, only required for CLN v23.08 and below
|
||||
// see https://docs.corelightning.org/docs/rest#server
|
||||
headers.append('nodeId', '02cb2e2d5a6c5b17fa67b1a883e2973c82e328fb9bd08b2b156a9e23820c87a490')
|
||||
return headers
|
||||
}
|
||||
|
||||
// https://github.com/clams-tech/rune-decoder/blob/57c2e76d1ef9ab7336f565b99de300da1c7b67ce/src/index.ts
|
||||
export const decodeRune = (rune) => {
|
||||
const runeBinary = Base64Binary.decode(rune)
|
||||
|
38
prisma/migrations/20250829002239_cln_send/migration.sql
Normal file
38
prisma/migrations/20250829002239_cln_send/migration.sql
Normal file
@ -0,0 +1,38 @@
|
||||
-- AlterEnum
|
||||
ALTER TYPE "WalletSendProtocolName" ADD VALUE 'CLN_REST'; COMMIT;
|
||||
|
||||
UPDATE "WalletTemplate" SET "sendProtocols" = array_append("sendProtocols", 'CLN_REST') WHERE "name" = 'CLN';
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "WalletSendCLNRest" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"protocolId" INTEGER NOT NULL,
|
||||
"socket" TEXT NOT NULL,
|
||||
"runeVaultId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "WalletSendCLNRest_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "WalletSendCLNRest_protocolId_key" ON "WalletSendCLNRest"("protocolId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "WalletSendCLNRest_runeVaultId_key" ON "WalletSendCLNRest"("runeVaultId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "WalletSendCLNRest" ADD CONSTRAINT "WalletSendCLNRest_protocolId_fkey" FOREIGN KEY ("protocolId") REFERENCES "WalletProtocol"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "WalletSendCLNRest" ADD CONSTRAINT "WalletSendCLNRest_runeVaultId_fkey" FOREIGN KEY ("runeVaultId") REFERENCES "Vault"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
CREATE TRIGGER wallet_to_jsonb
|
||||
AFTER INSERT OR UPDATE ON "WalletSendCLNRest"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE wallet_to_jsonb();
|
||||
|
||||
CREATE TRIGGER wallet_clear_vault
|
||||
AFTER DELETE ON "WalletSendCLNRest"
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE wallet_clear_vault();
|
@ -220,6 +220,7 @@ model Vault {
|
||||
walletSendLNCLocalKey WalletSendLNC? @relation("lncLocalKey")
|
||||
walletSendLNCRemoteKey WalletSendLNC? @relation("lncRemoteKey")
|
||||
walletSendLNCServerHost WalletSendLNC? @relation("lncServerHost")
|
||||
walletSendCLNRestRune WalletSendCLNRest? @relation("clnRune")
|
||||
}
|
||||
|
||||
model WalletLog {
|
||||
@ -1221,6 +1222,7 @@ enum WalletSendProtocolName {
|
||||
BLINK
|
||||
WEBLN
|
||||
LNC
|
||||
CLN_REST
|
||||
}
|
||||
|
||||
enum WalletRecvProtocolName {
|
||||
@ -1322,6 +1324,7 @@ model WalletProtocol {
|
||||
walletSendBlink WalletSendBlink?
|
||||
walletSendWebLN WalletSendWebLN?
|
||||
walletSendLNC WalletSendLNC?
|
||||
walletSendCLNRest WalletSendCLNRest?
|
||||
|
||||
walletRecvNWC WalletRecvNWC?
|
||||
walletRecvLNbits WalletRecvLNbits?
|
||||
@ -1403,6 +1406,17 @@ model WalletSendLNC {
|
||||
serverHost Vault? @relation("lncServerHost", fields: [serverHostVaultId], references: [id])
|
||||
}
|
||||
|
||||
model WalletSendCLNRest {
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
|
||||
protocolId Int @unique
|
||||
protocol WalletProtocol @relation(fields: [protocolId], references: [id], onDelete: Cascade)
|
||||
socket String
|
||||
runeVaultId Int @unique
|
||||
rune Vault? @relation("clnRune", fields: [runeVaultId], references: [id])
|
||||
}
|
||||
|
||||
model WalletRecvNWC {
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
25
scripts/clnrest_pay.sh
Executable file
25
scripts/clnrest_pay.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Sends a lightning payment using CLNRest
|
||||
# Usage: ./clnrest_pay.sh <bolt11>
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <bolt11>"
|
||||
echo "Example: $0 lnbc..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BOLT11=$1
|
||||
# add rune here
|
||||
# $ sndev cli cln createrune restrictions='[["method=pay"]]'
|
||||
RUNE=
|
||||
NODE_ID=02cb2e2d5a6c5b17fa67b1a883e2973c82e328fb9bd08b2b156a9e23820c87a490
|
||||
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Rune: $RUNE" \
|
||||
-H "nodeId: $NODE_ID" \
|
||||
-d "{\"bolt11\":\"$BOLT11\"}" \
|
||||
--cacert docker/cln/ca.pem \
|
||||
-v \
|
||||
https://localhost:9092/v1/pay
|
@ -151,6 +151,22 @@ export const UPSERT_WALLET_RECEIVE_NWC = gql`
|
||||
}
|
||||
`
|
||||
|
||||
export const UPSERT_WALLET_SEND_CLN_REST = gql`
|
||||
mutation upsertWalletSendCLNRest(
|
||||
${shared.variables},
|
||||
$socket: String!,
|
||||
$rune: VaultEntryInput!,
|
||||
) {
|
||||
upsertWalletSendCLNRest(
|
||||
${shared.arguments},
|
||||
socket: $socket,
|
||||
rune: $rune,
|
||||
) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const UPSERT_WALLET_RECEIVE_CLN_REST = gql`
|
||||
mutation upsertWalletRecvCLNRest(
|
||||
${shared.variables},
|
||||
|
@ -71,6 +71,13 @@ const WALLET_PROTOCOL_FIELDS = gql`
|
||||
...VaultEntryFields
|
||||
}
|
||||
}
|
||||
... on WalletSendCLNRest {
|
||||
id
|
||||
socket
|
||||
encryptedRune: rune {
|
||||
...VaultEntryFields
|
||||
}
|
||||
}
|
||||
... on WalletRecvNWC {
|
||||
id
|
||||
url
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
UPSERT_WALLET_SEND_NWC,
|
||||
UPSERT_WALLET_SEND_PHOENIXD,
|
||||
UPSERT_WALLET_SEND_WEBLN,
|
||||
UPSERT_WALLET_SEND_CLN_REST,
|
||||
WALLETS,
|
||||
UPDATE_WALLET_ENCRYPTION,
|
||||
RESET_WALLETS,
|
||||
@ -295,7 +296,7 @@ function protocolUpsertMutation (protocol) {
|
||||
case 'NWC':
|
||||
return protocol.send ? UPSERT_WALLET_SEND_NWC : UPSERT_WALLET_RECEIVE_NWC
|
||||
case 'CLN_REST':
|
||||
return protocol.send ? NOOP_MUTATION : UPSERT_WALLET_RECEIVE_CLN_REST
|
||||
return protocol.send ? UPSERT_WALLET_SEND_CLN_REST : UPSERT_WALLET_RECEIVE_CLN_REST
|
||||
case 'LND_GRPC':
|
||||
return protocol.send ? NOOP_MUTATION : UPSERT_WALLET_RECEIVE_LND_GRPC
|
||||
case 'LNC':
|
||||
|
13
wallets/client/protocols/clnRest.js
Normal file
13
wallets/client/protocols/clnRest.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { sendPayment as clnSendPayment } from '@/lib/cln'
|
||||
|
||||
export const name = 'CLN_REST'
|
||||
|
||||
export const sendPayment = async (bolt11, config, { signal }) => {
|
||||
return await clnSendPayment(bolt11, config, { signal })
|
||||
}
|
||||
|
||||
export const testSendPayment = async ({ socket, rune, cert }, { signal }) => {
|
||||
// We only can use the /pay endpoint with the rune so we can't
|
||||
// really test the configuration without paying something
|
||||
// until https://github.com/stackernews/stacker.news/issues/1287
|
||||
}
|
@ -4,6 +4,7 @@ import * as phoenixd from './phoenixd'
|
||||
import * as blink from './blink'
|
||||
import * as webln from './webln'
|
||||
import * as lnc from './lnc'
|
||||
import * as clnRest from './clnRest'
|
||||
|
||||
export * from './util'
|
||||
|
||||
@ -52,5 +53,6 @@ export default [
|
||||
phoenixd,
|
||||
blink,
|
||||
webln,
|
||||
lnc
|
||||
lnc,
|
||||
clnRest
|
||||
]
|
||||
|
@ -3,53 +3,93 @@ import { certValidator, runeValidator, socketValidator } from '@/wallets/lib//va
|
||||
// Core Lightning REST API
|
||||
// https://docs.corelightning.org/docs/rest
|
||||
|
||||
export default {
|
||||
name: 'CLN_REST',
|
||||
displayName: 'CLNRest',
|
||||
send: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'socket',
|
||||
label: 'rest host and port',
|
||||
type: 'text',
|
||||
placeholder: '55.5.555.55:3010',
|
||||
hint: 'tor or clearnet',
|
||||
required: true,
|
||||
validate: socketValidator()
|
||||
},
|
||||
{
|
||||
name: 'rune',
|
||||
label: 'invoice only rune',
|
||||
type: 'password',
|
||||
help: [
|
||||
'We only accept runes that *only* allow `method=invoice`.',
|
||||
'Run this to generate one if you are on v24.11 or later:',
|
||||
'```lightning-cli createrune restrictions=\'[["method=invoice"]]\'```',
|
||||
'Or this if you are on an earlier version:',
|
||||
'```lightning-cli createrune restrictions=\'["method=invoice"]\'```',
|
||||
'[see `createrune` documentation](https://docs.corelightning.org/reference/createrune#restriction-format)'
|
||||
],
|
||||
placeholder: 'S34KtUW-6gqS_hD_9cc_PNhfF-NinZyBOCgr1aIrark9NCZtZXRob2Q9aW52b2ljZQ==',
|
||||
validate: runeValidator({ method: 'invoice' }),
|
||||
required: true,
|
||||
hint: 'must be restricted to method=invoice'
|
||||
},
|
||||
{
|
||||
name: 'cert',
|
||||
label: 'certificate',
|
||||
type: 'password',
|
||||
placeholder: 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNNVENDQWRpZ0F3SUJBZ0lRSHBFdFdrcGJwZHV4RVF2eVBPc3NWVEFLQmdncWhrak9QUVFEQWpBdk1SOHcKSFFZRFZRUUtFeFpzYm1RZ1lYVjBiMmRsYm1WeVlYUmxaQ0JqWlhKME1Rd3dDZ1lEVlFRREV3TmliMkl3SGhjTgpNalF3TVRBM01qQXhORE0wV2hjTk1qVXdNekF6TWpBeE5ETTBXakF2TVI4d0hRWURWUVFLRXhac2JtUWdZWFYwCmIyZGxibVZ5WVhSbFpDQmpaWEowTVF3d0NnWURWUVFERXdOaWIySXdXVEFUQmdjcWhrak9QUUlCQmdncWhrak8KUFFNQkJ3TkNBQVJUS3NMVk5oZnhqb1FLVDlkVVdDbzUzSmQwTnBuL1BtYi9LUE02M1JxbU52dFYvdFk4NjJJZwpSbE41cmNHRnBEajhUeFc2OVhIK0pTcHpjWDdlN3N0Um80SFZNSUhTTUE0R0ExVWREd0VCL3dRRUF3SUNwREFUCkJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCVDAKMnh3V25GeHRUNzI0MWxwZlNoNm9FWi9UMWpCN0JnTlZIUkVFZERCeWdnTmliMktDQ1d4dlkyRnNhRzl6ZElJRApZbTlpZ2d4d2IyeGhjaTF1TVMxaWIyS0NGR2h2YzNRdVpHOWphMlZ5TG1sdWRHVnlibUZzZ2dSMWJtbDRnZ3AxCmJtbDRjR0ZqYTJWMGdnZGlkV1pqYjI1dWh3Ui9BQUFCaHhBQUFBQUFBQUFBQUFBQUFBQUFBQUFCaHdTc0VnQUQKTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUEwUTlkRXdoNXpPRnpwL3hYeHNpemh5SkxNVG5yazU1VWx1NHJPRwo4WW52QWlBVGt4U3p3Y3hZZnFscGx0UlNIbmd0NUJFcDBzcXlHL05nenBzb2pmMGNqQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K',
|
||||
hint: 'hex or base64 encoded',
|
||||
help: [
|
||||
'CLN generates self-signed TLS certificates on startup.',
|
||||
'The certificate of the certificate authority (CA) is needed to use them.',
|
||||
'By default, it is saved at $HOME/.lightning/bitcoin/ca.pem.',
|
||||
'This is optional if you are using a common certificate authority (e.g. cloud-hosted platform like Voltage).',
|
||||
'[see documentation](https://docs.corelightning.org/docs/grpc#generating-the-certificates)'
|
||||
],
|
||||
validate: certValidator(),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
relationName: 'walletRecvCLNRest'
|
||||
}
|
||||
export default [
|
||||
{
|
||||
name: 'CLN_REST',
|
||||
displayName: 'CLNRest',
|
||||
send: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'socket',
|
||||
label: 'rest host and port',
|
||||
type: 'text',
|
||||
placeholder: '55.5.555.55:3010',
|
||||
hint: 'tor or clearnet',
|
||||
required: true,
|
||||
validate: socketValidator(),
|
||||
share: true
|
||||
},
|
||||
{
|
||||
name: 'rune',
|
||||
label: 'invoice only rune',
|
||||
type: 'password',
|
||||
help: [
|
||||
'We only accept runes that *only* allow `method=invoice`.',
|
||||
'Run this to generate one if you are on v24.11 or later:',
|
||||
'```lightning-cli createrune restrictions=\'[["method=invoice"]]\'```',
|
||||
'Or this if you are on an earlier version:',
|
||||
'```lightning-cli createrune restrictions=\'["method=invoice"]\'```',
|
||||
'[see `createrune` documentation](https://docs.corelightning.org/reference/createrune#restriction-format)'
|
||||
],
|
||||
placeholder: 'S34KtUW-6gqS_hD_9cc_PNhfF-NinZyBOCgr1aIrark9NCZtZXRob2Q9aW52b2ljZQ==',
|
||||
validate: runeValidator({ method: 'invoice' }),
|
||||
required: true,
|
||||
hint: 'must be restricted to method=invoice'
|
||||
},
|
||||
{
|
||||
name: 'cert',
|
||||
label: 'certificate',
|
||||
type: 'password',
|
||||
placeholder: 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNNVENDQWRpZ0F3SUJBZ0lRSHBFdFdrcGJwZHV4RVF2eVBPc3NWVEFLQmdncWhrak9QUVFEQWpBdk1SOHcKSFFZRFZRUUtFeFpzYm1RZ1lYVjBiMmRsYm1WeVlYUmxaQ0JqWlhKME1Rd3dDZ1lEVlFRREV3TmliMkl3SGhjTgpNalF3TVRBM01qQXhORE0wV2hjTk1qVXdNekF6TWpBeE5ETTBXakF2TVI4d0hRWURWUVFLRXhac2JtUWdZWFYwCmIyZGxibVZ5WVhSbFpDQmpaWEowTVF3d0NnWURWUVFERXdOaWIySXdXVEFUQmdjcWhrak9QUUlCQmdncWhrak8KUFFNQkJ3TkNBQVJUS3NMVk5oZnhqb1FLVDlkVVdDbzUzSmQwTnBuL1BtYi9LUE02M1JxbU52dFYvdFk4NjJJZwpSbE41cmNHRnBEajhUeFc2OVhIK0pTcHpjWDdlN3N0Um80SFZNSUhTTUE0R0ExVWREd0VCL3dRRUF3SUNwREFUCkJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCVDAKMnh3V25GeHRUNzI0MWxwZlNoNm9FWi9UMWpCN0JnTlZIUkVFZERCeWdnTmliMktDQ1d4dlkyRnNhRzl6ZElJRApZbTlpZ2d4d2IyeGhjaTF1TVMxaWIyS0NGR2h2YzNRdVpHOWphMlZ5TG1sdWRHVnlibUZzZ2dSMWJtbDRnZ3AxCmJtbDRjR0ZqYTJWMGdnZGlkV1pqYjI1dWh3Ui9BQUFCaHhBQUFBQUFBQUFBQUFBQUFBQUFBQUFCaHdTc0VnQUQKTUFvR0NDcUdTTTQ5QkFNQ0EwY0FNRVFDSUEwUTlkRXdoNXpPRnpwL3hYeHNpemh5SkxNVG5yazU1VWx1NHJPRwo4WW52QWlBVGt4U3p3Y3hZZnFscGx0UlNIbmd0NUJFcDBzcXlHL05nenBzb2pmMGNqQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K',
|
||||
hint: 'hex or base64 encoded',
|
||||
help: [
|
||||
'CLN generates self-signed TLS certificates on startup.',
|
||||
'The certificate of the certificate authority (CA) is needed to use them.',
|
||||
'By default, it is saved at $HOME/.lightning/bitcoin/ca.pem.',
|
||||
'This is optional if you are using a common certificate authority (e.g. cloud-hosted platform like Voltage).',
|
||||
'[see documentation](https://docs.corelightning.org/docs/grpc#generating-the-certificates)'
|
||||
],
|
||||
validate: certValidator(),
|
||||
required: false
|
||||
}
|
||||
],
|
||||
relationName: 'walletRecvCLNRest'
|
||||
},
|
||||
{
|
||||
name: 'CLN_REST',
|
||||
displayName: 'CLNRest',
|
||||
send: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'socket',
|
||||
label: 'rest host and port',
|
||||
type: 'text',
|
||||
placeholder: '55.5.555.55:3010',
|
||||
required: true,
|
||||
validate: socketValidator(),
|
||||
share: true
|
||||
},
|
||||
{
|
||||
name: 'rune',
|
||||
label: 'pay only rune',
|
||||
type: 'password',
|
||||
help: [
|
||||
'We only accept runes that *only* allow `method=pay`.',
|
||||
'Run this to generate one if you are on v24.11 or later:',
|
||||
'```lightning-cli createrune restrictions=\'[["method=pay"]]\'```',
|
||||
'Or this if you are on an earlier version:',
|
||||
'```lightning-cli createrune restrictions=\'["method=pay"]\'```',
|
||||
'[see `createrune` documentation](https://docs.corelightning.org/reference/createrune#restriction-format)'
|
||||
],
|
||||
placeholder: 'S34KtUW-6gqS_hD_9cc_PNhfF-NinZyBOCgr1aIrark9NCZtZXRob2Q9aW52b2ljZQ==',
|
||||
validate: runeValidator({ method: 'pay' }),
|
||||
required: true,
|
||||
encrypt: true,
|
||||
hint: 'must be restricted to method=pay'
|
||||
}
|
||||
// XXX we don't ask for the CA certificate because the browser's fetch API doesn't support http agents to override it.
|
||||
// Therefore, CLNRest send will only work with common CA certificates.
|
||||
],
|
||||
relationName: 'walletSendCLNRest'
|
||||
}
|
||||
]
|
||||
|
@ -1,33 +1,11 @@
|
||||
To attach CLNRest as an receiving wallet protocol, you'll need a rune and the cert.
|
||||
# CLNRest
|
||||
|
||||
# host and port
|
||||
to attach sending:
|
||||
|
||||
`cln:3010`
|
||||
- socket: `localhost:9092`
|
||||
- rune: `sndev cli cln --regtest createrune restrictions='[["method=pay"]]'`
|
||||
|
||||
# host and port (onion)
|
||||
to attach receiving:
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
sndev onion cln
|
||||
```
|
||||
|
||||
# create rune
|
||||
|
||||
```bash
|
||||
sndev cli cln --regtest createrune restrictions='["method=invoice"]'
|
||||
```
|
||||
|
||||
# get cert
|
||||
|
||||
This is static in dev env so you can use this one:
|
||||
|
||||
```bash
|
||||
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tDQpNSUlCY2pDQ0FSaWdBd0lCQWdJSkFOclN2UFovWTNLRU1Bb0dDQ3FHU000OUJBTUNNQll4RkRBU0JnTlZCQU1NDQpDMk5zYmlCU2IyOTBJRU5CTUNBWERUYzFNREV3TVRBd01EQXdNRm9ZRHpRd09UWXdNVEF4TURBd01EQXdXakFXDQpNUlF3RWdZRFZRUUREQXRqYkc0Z1VtOXZkQ0JEUVRCWk1CTUdCeXFHU000OUFnRUdDQ3FHU000OUF3RUhBMElBDQpCQmptYUh1dWxjZ3dTR09ubExBSFlRbFBTUXdHWEROSld5ZnpWclY5aFRGYUJSZFFrMVl1Y3VqVFE5QXFybkVJDQpyRmR6MS9PeisyWFhENmdBMnhPbmIrNmpUVEJMTUJrR0ExVWRFUVFTTUJDQ0EyTnNib0lKYkc5allXeG9iM04wDQpNQjBHQTFVZERnUVdCQlNFY21OLzlyelMyaFI2RzdFSWdzWCs1MU4wQ2pBUEJnTlZIUk1CQWY4RUJUQURBUUgvDQpNQW9HQ0NxR1NNNDlCQU1DQTBnQU1FVUNJSENlUHZOU3Z5aUJZYXdxS2dRcXV3OUoyV1Z5SnhuMk1JWUlxejlTDQpRTDE4QWlFQWg4QlZEejhwWDdOc2xsOHNiMGJPMFJaNDljdnFRb2NDZ1ZhYnFKdVN1aWs9DQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tDQo=
|
||||
```
|
||||
|
||||
Which is generated with the following command
|
||||
|
||||
```bash
|
||||
openssl base64 -A -in docker/cln/ca.pem
|
||||
```
|
||||
- socket: `cln:3010` or onion via `sndev onion cln`
|
||||
- rune: `sndev cli cln --regtest createrune restrictions='[["method=invoice"]]'`
|
||||
|
@ -1,6 +1,6 @@
|
||||
import nwcSuite from './nwc'
|
||||
import lnAddr from './lnAddr'
|
||||
import clnRest from './clnRest'
|
||||
import clnRestSuite from './clnRest'
|
||||
import lndGrpc from './lndGrpc'
|
||||
import lnc from './lnc'
|
||||
import lnbitsSuite from './lnbits'
|
||||
@ -39,7 +39,7 @@ import webln from './webln'
|
||||
export default [
|
||||
...nwcSuite,
|
||||
lnAddr,
|
||||
clnRest,
|
||||
...clnRestSuite,
|
||||
lndGrpc,
|
||||
lnc,
|
||||
...phoenixdSuite,
|
||||
|
@ -16,7 +16,7 @@ export function mapWalletResolveTypes (wallet) {
|
||||
case 'LNC':
|
||||
return 'WalletSendLNC'
|
||||
case 'CLN_REST':
|
||||
return 'WalletRecvCLNRest'
|
||||
return send ? 'WalletSendCLNRest' : 'WalletRecvCLNRest'
|
||||
case 'LND_GRPC':
|
||||
return 'WalletRecvLNDGRPC'
|
||||
default:
|
||||
|
Loading…
x
Reference in New Issue
Block a user