WIP Persist zaps, create and send zap receipts
This commit is contained in:
@@ -1,7 +1,20 @@
|
||||
FactoryBot.define do
|
||||
factory :zap do
|
||||
user { nil }
|
||||
request { "" }
|
||||
receipt { "" }
|
||||
request {
|
||||
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"
|
||||
).to_h
|
||||
}
|
||||
payment_request { "lnbc1u1p3mull3pp5qw4x46ew6kjknudypyjsg8maw935tr5kkuz7t6h7pugp3pt4msyqhp5zp40yd97a028sgr9x4yxq5d57gft6vwja58e8cl0eea4uasr6apscqzpgxqyz5vqsp53m2n8h6yeflgukv5fhwm802kur6un9w8nvycl7auk67w5g2u008q9qyyssqml8rfmxyvp32qd5939qx7uu0w6ppjuujlpwsrz28m9u0dzp799hz5j72w0xm8pg97hd4hdvwh9zxaw2hewnnmzewvc550f9y3qsfaegphmk0mu" }
|
||||
receipt { nil }
|
||||
end
|
||||
end
|
||||
|
||||
2
spec/fixtures/lndhub/incoming-zap.json
vendored
2
spec/fixtures/lndhub/incoming-zap.json
vendored
@@ -4,7 +4,7 @@
|
||||
"user_login": "123456abcdef",
|
||||
"amount": 21000,
|
||||
"fee": 0,
|
||||
"memo": "{\"id\":\"3cf02d7f0ccd9711c25098fc50b3a7ab880326e4e51cc8c7a7b59f147cff4fff\",\"sig\":\"e9e9bb2bac4267a107ab5c3368f504b4f11b8e3b5ae875a1d63c74d6934138d2521dc35815b6f534fc5d803cbf633736d871886368bb8f92c4ad3837a68a06f2\",\"pubkey\":\"730b43e6f62c2ab22710b046e481802c8ac1108ed2cb9c21dff808d57ba24b6c\",\"created_at\":1712487443,\"kind\":9734,\"tags\":[[\"relays\",\"wss://nostr.kosmos.org\",\"wss://relay.example.com\"],[\"p\",\"07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3\"]],\"content\":\"\"}",
|
||||
"memo": "Zap for satoshi@kosmos.org",
|
||||
"description_hash": "b1a9910724bc9c1b03b4eba2e2d78ac69a8ac7b244e6ff6d4e7391bf6893f26a",
|
||||
"payment_request": "lnbc1u1p3mull3pp5qw4x46ew6kjknudypyjsg8maw935tr5kkuz7t6h7pugp3pt4msyqhp5zp40yd97a028sgr9x4yxq5d57gft6vwja58e8cl0eea4uasr6apscqzpgxqyz5vqsp53m2n8h6yeflgukv5fhwm802kur6un9w8nvycl7auk67w5g2u008q9qyyssqml8rfmxyvp32qd5939qx7uu0w6ppjuujlpwsrz28m9u0dzp799hz5j72w0xm8pg97hd4hdvwh9zxaw2hewnnmzewvc550f9y3qsfaegphmk0mu",
|
||||
"destination_pubkey_hex": "024cd3be18617f39cf645851e3ba63f51fc13f0bb09e3bb25e6fd4de556486d946",
|
||||
|
||||
12
spec/models/zap_spec.rb
Normal file
12
spec/models/zap_spec.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Zap, type: :model do
|
||||
describe "#request_event" do
|
||||
let(:user) { create :user, cn: 'satoshi', ou: 'kosmos.org', ln_account: 'abcdefg123456' }
|
||||
let(:zap) { create :zap, user: user }
|
||||
|
||||
it "returns the stored request as a Nostr::Event" do
|
||||
expect(zap.request_event).to be_a(Nostr::Event)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -143,7 +143,7 @@ RSpec.describe "/lnurlpay", type: :request do
|
||||
expect(LndhubManager::CreateUserInvoice).to receive(:call)
|
||||
.with(user: user, payload: {
|
||||
amount: 21,
|
||||
description: event.to_json,
|
||||
description: "Zap for satoshi@kosmos.org",
|
||||
description_hash: "b1a9910724bc9c1b03b4eba2e2d78ac69a8ac7b244e6ff6d4e7391bf6893f26a"
|
||||
})
|
||||
.and_return(invoice)
|
||||
@@ -156,7 +156,17 @@ RSpec.describe "/lnurlpay", type: :request do
|
||||
|
||||
res = JSON.parse(response.body)
|
||||
expect(res["status"]).to eq('OK')
|
||||
expect(res["pr"]).to eq("lnbc210n1pnzzyvjpp56map6jmxtpaty37hk8mkpre2a4uq5rx2qgwsngcz08pam8lcp7zshp5xs7v3qlx0j0gyu9grrzx9xgews3t9vq64v30579le9z9wqr6fc5scqzzsxqyz5vqsp5kmltj5eayh47c6trwj8wdrz5nxymqp0eqwtk7k5nk6ytyz522nvs9qyyssqvkluufkp34gtzxdg0uyqcsdum2n34xz94tqr4jfwwx53czteutvj7eptz4lm5vcu0m8jqzxck484ycxzcqgqlqmpj2r3jxjlj4x6nygp8fvnag")
|
||||
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
|
||||
|
||||
@@ -110,17 +110,48 @@ RSpec.describe "Webhooks", type: :request do
|
||||
|
||||
describe "Valid payload for zap transaction" do
|
||||
let(:user) { create :user, ln_account: "123456abcdef" }
|
||||
let(:zap) { create :zap, user: user }
|
||||
let(:payload) { JSON.parse(File.read(File.expand_path("../fixtures/lndhub/incoming-zap.json", File.dirname(__FILE__)))) }
|
||||
let(:zap_receipt) {
|
||||
Nostr::Event.new(
|
||||
id: "cb66278a9add37a2f1e018826327ff15304e8055ff7b910100225baf83a9d691",
|
||||
sig: "a808d6792e21824bfddc98742b6831b1070e8b21e12aa424d2bb168a09f3a95a217d4513e803f2acb6e38404f763eb09fa07a341ee9c8c4c7d18bbe3d381eb6f",
|
||||
pubkey: "bdd76ce2934b2f591f9fad2ebe9da18f20d2921de527494ba00eeaa0a0efadcf",
|
||||
created_at: 1673428978,
|
||||
kind: 9735,
|
||||
tags: [
|
||||
["p", "07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3"],
|
||||
["bolt11", "lnbc1u1p3mull3pp5qw4x46ew6kjknudypyjsg8maw935tr5kkuz7t6h7pugp3pt4msyqhp5zp40yd97a028sgr9x4yxq5d57gft6vwja58e8cl0eea4uasr6apscqzpgxqyz5vqsp53m2n8h6yeflgukv5fhwm802kur6un9w8nvycl7auk67w5g2u008q9qyyssqml8rfmxyvp32qd5939qx7uu0w6ppjuujlpwsrz28m9u0dzp799hz5j72w0xm8pg97hd4hdvwh9zxaw2hewnnmzewvc550f9y3qsfaegphmk0mu"],
|
||||
["preimage", "3539663535656537343331663432653165396430623966633664656664646563"],
|
||||
["description", "{\"id\":\"3cf02d7f0ccd9711c25098fc50b3a7ab880326e4e51cc8c7a7b59f147cff4fff\",\"sig\":\"e9e9bb2bac4267a107ab5c3368f504b4f11b8e3b5ae875a1d63c74d6934138d2521dc35815b6f534fc5d803cbf633736d871886368bb8f92c4ad3837a68a06f2\",\"pubkey\":\"730b43e6f62c2ab22710b046e481802c8ac1108ed2cb9c21dff808d57ba24b6c\",\"created_at\":1712487443,\"kind\":9734,\"tags\":[[\"relays\",\"wss://nostr.kosmos.org\",\"wss://relay.example.com\"],[\"p\",\"07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3\"]],\"content\":\"\"}"]
|
||||
],
|
||||
content: ""
|
||||
)
|
||||
}
|
||||
|
||||
before { user.save! } #FIXME this should not be necessary
|
||||
before do
|
||||
user.save!
|
||||
zap.save!
|
||||
|
||||
allow(NostrManager::CreateZapReceipt).to receive(:call)
|
||||
.and_return(zap_receipt)
|
||||
allow(NostrManager::PublishZapReceipt).to receive(:call)
|
||||
.and_return(true)
|
||||
end
|
||||
|
||||
it "returns a 200 status" do
|
||||
post "/webhooks/lndhub", params: payload.to_json
|
||||
expect(response).to have_http_status(:ok)
|
||||
end
|
||||
|
||||
it "sends a zap receipt" do
|
||||
expect(NostrManager::PublishZapReceipt).to receive(:call)
|
||||
it "creates and adds a zap receipt to the zap record" do
|
||||
post "/webhooks/lndhub", params: payload.to_json
|
||||
zap = user.zaps.first
|
||||
expect(zap.receipt).not_to be_nil
|
||||
end
|
||||
|
||||
it "publishes the zap receipt" do
|
||||
expect(NostrManager::PublishZapReceipt).to receive(:call).with(zap: zap)
|
||||
post "/webhooks/lndhub", params: payload.to_json
|
||||
end
|
||||
end
|
||||
|
||||
45
spec/services/nostr_manager/create_zap_receipt_spec.rb
Normal file
45
spec/services/nostr_manager/create_zap_receipt_spec.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe NostrManager::CreateZapReceipt, type: :model do
|
||||
let(:user) { create :user, ln_account: "123456abcdef" }
|
||||
let(:zap) { create :zap, user: user }
|
||||
|
||||
# before do
|
||||
# user.save!
|
||||
# zap.save!
|
||||
# end
|
||||
|
||||
subject {
|
||||
described_class.call(
|
||||
zap: zap, paid_at: 1673428978,
|
||||
preimage: "3539663535656537343331663432653165396430623966633664656664646563"
|
||||
)
|
||||
}
|
||||
|
||||
describe "Zap receipt" do
|
||||
it "is a kind:9735 note" do
|
||||
expect(subject).to be_a(Nostr::Event)
|
||||
expect(subject.kind).to eq(9735)
|
||||
end
|
||||
|
||||
it "sets created_at to when the invoice was paid" do
|
||||
expect(subject.created_at).to eq(1673428978)
|
||||
end
|
||||
|
||||
it "contains the zap recipient" do
|
||||
expect(subject.tags.find{|t| t[0] == "p"}[1]).to eq("07e188a1ff87ce171d517b8ed2bb7a31b1d3453a0db3b15379ec07b724d232f3")
|
||||
end
|
||||
|
||||
it "contains the bolt11 invoice" do
|
||||
expect(subject.tags.find{|t| t[0] == "bolt11"}[1]).to eq(zap.payment_request)
|
||||
end
|
||||
|
||||
it "contains the invoice preimage" do
|
||||
expect(subject.tags.find{|t| t[0] == "preimage"}[1]).to eq("3539663535656537343331663432653165396430623966633664656664646563")
|
||||
end
|
||||
|
||||
it "contains the serialized zap request event as description" do
|
||||
expect(subject.tags.find{|t| t[0] == "description"}[1]).to eq(zap.request_event.to_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
16
spec/services/nostr_manager/publish_zap_receipt_spec.rb
Normal file
16
spec/services/nostr_manager/publish_zap_receipt_spec.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe NostrManager::PublishZapReceipt, type: :model do
|
||||
let(:user) { create :user, ln_account: "123456abcdef" }
|
||||
let(:zap) { create :zap, user: user }
|
||||
|
||||
describe "Default/delayed execution" do
|
||||
it "publishes zap receipts to all requested relays" do
|
||||
2.times do
|
||||
expect(NostrPublishEventJob).to receive(:perform_later).and_return(true)
|
||||
end
|
||||
|
||||
described_class.call(zap: zap)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user