211 lines
7.9 KiB
Ruby
211 lines
7.9 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe "/lnurlpay", type: :request do
|
|
context "Non-existent user" do
|
|
describe "GET /.well-known/lnurlp/:username" do
|
|
it "returns a 404" do
|
|
get lightning_address_path(username: "csw")
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
|
|
describe "GET /lnurlpay/:username/invoice" do
|
|
it "returns a 404" do
|
|
get lnurlpay_invoice_path(username: "csw", params: { amount: 5000 })
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
|
|
describe "GET /.well-known/keysend/:username/" do
|
|
it "returns a 404" do
|
|
get lightning_address_keysend_path(username: "csw")
|
|
expect(response).to have_http_status(:not_found)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "Valid user" do
|
|
let(:user) { create :user, cn: 'satoshi', ou: 'kosmos.org', lndhub_username: 'abcdefg123456' }
|
|
|
|
before do
|
|
login_as user, :scope => :user
|
|
Setting.nostr_enabled = false
|
|
end
|
|
|
|
describe "GET /.well-known/lnurlp/:username" do
|
|
it "returns a formatted Lightning Address response" do
|
|
get lightning_address_path(username: "satoshi")
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('OK')
|
|
expect(res["tag"]).to eq('payRequest')
|
|
expect(res["callback"]).to match(lnurlpay_invoice_path('satoshi'))
|
|
expect(res["minSendable"]).to be_a(Integer)
|
|
expect(res["maxSendable"]).to be_a(Integer)
|
|
expect(res["commentAllowed"]).to be_a(Integer)
|
|
expect(res["allowsNostr"]).to be_nil
|
|
end
|
|
|
|
context "with support for nostr zaps" do
|
|
before do
|
|
Setting.nostr_enabled = true
|
|
end
|
|
|
|
it "returns NIP-57 properties" do
|
|
get lightning_address_path(username: "satoshi")
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["allowsNostr"]).to be(true)
|
|
expect(res["nostrPubkey"]).to eq(Setting.nostr_public_key)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "GET /lnurlpay/:username/invoice" do
|
|
let(:invoice) {
|
|
{
|
|
"payment_hash" => "35778ccdb8319b5104e41d2043d18446bf91bcd51450b5f1cf1b6082a7cc6203",
|
|
"payment_request" => "lnbc210n1pnzzr6rpp5x4mcendcxxd4zp8yr5sy85vyg6ler0x4z3gttuw0rdsg9f7vvgpshp52y6nf64apaqta2kjuwp2apglewqa9fva2mada6x2mmdj20t57jdscqzzsxqyz5vqsp5a3h88efdc436wunupz293gdtvm5843yfcfc8hxm2rpdunaetl39q9qyyssq07ec02dqr4epa73ssy0lzwglw49aa9rfywlp0c7jpnf448uapsgqch79d4222xqlh8674lzddvcyptpnwqqq8vpppf8djrn8yjf53dqpzwx5kh",
|
|
"expires_at" => "2024-04-19T12:17:07.725314947Z"
|
|
}
|
|
}
|
|
|
|
before do
|
|
allow(LndhubManager::CreateUserInvoice).to receive(:call)
|
|
.and_return(invoice)
|
|
end
|
|
|
|
it "returns a formatted lnurlpay response" do
|
|
get lnurlpay_invoice_path(username: "satoshi", params: {
|
|
amount: 21000, comment: "Coffee time!"
|
|
})
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('OK')
|
|
expect(res["successAction"]["tag"]).to eq('message')
|
|
expect(res["successAction"]["message"]).to match('Thank you')
|
|
expect(res["pr"]).to eq("lnbc210n1pnzzr6rpp5x4mcendcxxd4zp8yr5sy85vyg6ler0x4z3gttuw0rdsg9f7vvgpshp52y6nf64apaqta2kjuwp2apglewqa9fva2mada6x2mmdj20t57jdscqzzsxqyz5vqsp5a3h88efdc436wunupz293gdtvm5843yfcfc8hxm2rpdunaetl39q9qyyssq07ec02dqr4epa73ssy0lzwglw49aa9rfywlp0c7jpnf448uapsgqch79d4222xqlh8674lzddvcyptpnwqqq8vpppf8djrn8yjf53dqpzwx5kh")
|
|
end
|
|
|
|
describe "amount too low" do
|
|
it "returns an error" do
|
|
get lnurlpay_invoice_path(username: "satoshi", params: {
|
|
amount: 5000, comment: "Coffee time!"
|
|
})
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('ERROR')
|
|
expect(res["reason"]).to eq('Invalid amount')
|
|
end
|
|
end
|
|
|
|
describe "comment too long" do
|
|
it "returns an error" do
|
|
get lnurlpay_invoice_path(username: "satoshi", params: {
|
|
amount: 5000000, comment: "Coffee time is the best time, so here's some money for you to get some. May I suggest to sample some Pacamara beans from El Salvador?"
|
|
})
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('ERROR')
|
|
expect(res["reason"]).to eq('Comment too long')
|
|
end
|
|
end
|
|
|
|
context "zap request" do
|
|
before do
|
|
Setting.nostr_enabled = true
|
|
end
|
|
|
|
describe "with invalid request event" do
|
|
it "returns an error" do
|
|
get lnurlpay_invoice_path(username: "satoshi", params: {
|
|
amount: 2100000, nostr: { foo: "bar" }.to_json
|
|
})
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('ERROR')
|
|
expect(res["reason"]).to eq('Invalid zap request')
|
|
end
|
|
end
|
|
|
|
describe "with valid request event" do
|
|
let(:event) {
|
|
Nostr::Event.new(
|
|
id: "3cf02d7f0ccd9711c25098fc50b3a7ab880326e4e51cc8c7a7b59f147cff4fff",
|
|
pubkey: "730b43e6f62c2ab22710b046e481802c8ac1108ed2cb9c21dff808d57ba24b6c",
|
|
created_at: 1712487443,
|
|
kind: 9734,
|
|
tags: [
|
|
["relays", "wss://nostr.kosmos.org", "wss://relay.example.com"],
|
|
["p", "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"]],
|
|
content: "",
|
|
sig: "e9e9bb2bac4267a107ab5c3368f504b4f11b8e3b5ae875a1d63c74d6934138d2521dc35815b6f534fc5d803cbf633736d871886368bb8f92c4ad3837a68a06f2"
|
|
)
|
|
}
|
|
|
|
let(:invoice) {
|
|
{
|
|
"payment_hash" => "d6fa1d4b66587ab247d7b1f7608f2aed780a0cca021d09a30279c3dd9ff80f85",
|
|
"payment_request" => "lnbc210n1pnzzyvjpp56map6jmxtpaty37hk8mkpre2a4uq5rx2qgwsngcz08pam8lcp7zshp5xs7v3qlx0j0gyu9grrzx9xgews3t9vq64v30579le9z9wqr6fc5scqzzsxqyz5vqsp5kmltj5eayh47c6trwj8wdrz5nxymqp0eqwtk7k5nk6ytyz522nvs9qyyssqvkluufkp34gtzxdg0uyqcsdum2n34xz94tqr4jfwwx53czteutvj7eptz4lm5vcu0m8jqzxck484ycxzcqgqlqmpj2r3jxjlj4x6nygp8fvnag",
|
|
"expires_at" => "2024-04-19T12:26:58.432434748Z"
|
|
}
|
|
}
|
|
|
|
it "returns an invoice" do
|
|
expect(LndhubManager::CreateUserInvoice).to receive(:call)
|
|
.with(user: user, payload: {
|
|
amount: 21,
|
|
description: "Zap for satoshi@kosmos.org",
|
|
description_hash: "b1a9910724bc9c1b03b4eba2e2d78ac69a8ac7b244e6ff6d4e7391bf6893f26a"
|
|
})
|
|
.and_return(invoice)
|
|
|
|
get lnurlpay_invoice_path(username: "satoshi", params: {
|
|
amount: 21000, nostr: event.to_json
|
|
})
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('OK')
|
|
expect(res["pr"]).to eq(invoice["payment_request"])
|
|
end
|
|
|
|
it "creates a zap record" do
|
|
get lnurlpay_invoice_path(username: "satoshi", params: {
|
|
amount: 21000, nostr: event.to_json
|
|
})
|
|
|
|
zap = user.zaps.find_by payment_request: invoice["payment_request"]
|
|
expect(zap.request_event.id).to eq(event.id)
|
|
expect(zap.receipt).to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "GET /.well-known/keysend/:username/" do
|
|
it "returns a formatted Lightning Address keysend response" do
|
|
get lightning_address_keysend_path(username: "satoshi")
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
res = JSON.parse(response.body)
|
|
expect(res["status"]).to eq('OK')
|
|
expect(res["tag"]).to eq('keysend')
|
|
expect(res["pubkey"]).to eq(Setting.lndhub_public_key)
|
|
expect(res["customData"][0]["customKey"]).to eq('696969')
|
|
expect(res["customData"][0]["customValue"]).to eq('abcdefg123456')
|
|
end
|
|
end
|
|
end
|
|
end
|