diff --git a/create_db.sql b/create_db.sql index ace2191..171944f 100644 --- a/create_db.sql +++ b/create_db.sql @@ -41,5 +41,18 @@ CREATE TABLE card_payments ( CONSTRAINT fk_card FOREIGN KEY(card_id) REFERENCES cards(card_id) ); +CREATE TABLE card_receipts ( + card_receipt_id INT GENERATED ALWAYS AS IDENTITY, + card_id INT NOT NULL, + ln_invoice VARCHAR(1024) NOT NULL DEFAULT '', + r_hash_hex VARCHAR(64) UNIQUE NOT NULL DEFAULT '', + amount_msats BIGINT CHECK (amount_msats > 0), + receipt_status VARCHAR(100) NOT NULL DEFAULT '', + receipt_status_time TIMESTAMPTZ, + CONSTRAINT fk_card FOREIGN KEY(card_id) REFERENCES cards(card_id) +); + GRANT ALL PRIVILEGES ON TABLE cards TO cardapp; GRANT ALL PRIVILEGES ON TABLE card_payments TO cardapp; +GRANT ALL PRIVILEGES ON TABLE card_receipts TO cardapp; + diff --git a/database.go b/database.go index b41dc34..03cd930 100644 --- a/database.go +++ b/database.go @@ -106,7 +106,7 @@ func db_get_card_count_for_uid(uid string) (int, error) { return card_count, nil } -func db_get_card_count_for_name(name string) (int, error) { +func db_get_card_count_for_name_enabled(name string) (int, error) { card_count := 0 @@ -116,7 +116,7 @@ func db_get_card_count_for_name(name string) (int, error) { } defer db.Close() - sqlStatement := `select count(card_id) from cards where card_name=$1;` + sqlStatement := `select count(card_id) from cards where card_name=$1 and enable_flag='Y';` row := db.QueryRow(sqlStatement, name) err = row.Scan(&card_count) @@ -127,6 +127,27 @@ func db_get_card_count_for_name(name string) (int, error) { return card_count, nil } +func db_get_card_id_for_name(name string) (int, error) { + + card_id := 0 + + db, err := db_open() + if err != nil { + return 0, err + } + defer db.Close() + + sqlStatement := `select card_id from cards where card_name=$1;` + + row := db.QueryRow(sqlStatement, name) + err = row.Scan(&card_id) + if err != nil { + return 0, err + } + + return card_id, nil +} + func db_get_cards_blank_uid() ([]Card, error) { // open the database @@ -335,6 +356,63 @@ func db_insert_payment(card_id int, lnurlw_k1 string) error { return nil } +func db_insert_receipt( + card_id int, + ln_invoice string, + r_hash_hex string, + amount_msat int64) error { + + db, err := db_open() + if err != nil { + return err + } + defer db.Close() + + // insert a new record into card_receipts + + sqlStatement := `INSERT INTO card_receipts` + + ` (card_id, ln_invoice, r_hash_hex, amount_msats, receipt_status_time)` + + ` VALUES ($1, $2, $3, $4, NOW());` + res, err := db.Exec(sqlStatement, card_id, ln_invoice, r_hash_hex, amount_msat) + if err != nil { + return err + } + count, err := res.RowsAffected() + if err != nil { + return err + } + if count != 1 { + return errors.New("not one card_receipts record inserted") + } + + return nil +} + +func db_update_receipt_state(r_hash_hex string, invoice_state string) error { + db, err := db_open() + if err != nil { + return err + } + defer db.Close() + + sqlStatement := `UPDATE card_receipts ` + + `SET receipt_status = $2, receipt_status_time = NOW() ` + + `WHERE r_hash_hex = $1;` + res, err := db.Exec(sqlStatement, r_hash_hex, invoice_state) + if err != nil { + return err + } + count, err := res.RowsAffected() + if err != nil { + return err + } + if count != 1 { + return errors.New("not one card_receipts record updated") + } + + return nil +} + func db_get_payment_k1(lnurlw_k1 string) (*payment, error) { p := payment{} @@ -376,7 +454,7 @@ func db_update_payment_invoice(card_payment_id int, ln_invoice string, amount_ms return err } if count != 1 { - return errors.New("not one card_payment record updated") + return errors.New("not one card_payments record updated") } return nil diff --git a/lightning.go b/lightning.go index 07b1bf5..9fdb055 100644 --- a/lightning.go +++ b/lightning.go @@ -153,7 +153,7 @@ func monitor_invoice_state(r_hash []byte) () { "invoice_state": invoice_state, },).Info("invoice state updated") -//TODO: update database + db_update_receipt_state(hex.EncodeToString(r_hash), invoice_state) } connection.Close() diff --git a/lnurlp_callback.go b/lnurlp_callback.go index 60435ec..888f0f3 100644 --- a/lnurlp_callback.go +++ b/lnurlp_callback.go @@ -6,16 +6,25 @@ import ( "github.com/gorilla/mux" "net/http" "strconv" + "encoding/hex" ) func lnurlp_callback(w http.ResponseWriter, r *http.Request) { name := mux.Vars(r)["name"] - amount := r.URL.Query().Get("amount"); + amount := r.URL.Query().Get("amount") + + card_id, err := db_get_card_id_for_name(name) + if err != nil { + log.Info("card name not found") + write_error(w) + return + } log.WithFields( log.Fields{ "url_path": r.URL.Path, "name": name, + "card_id": card_id, "amount": amount, "req.Host": r.Host, },).Info("lnurlp_callback") @@ -27,13 +36,29 @@ func lnurlp_callback(w http.ResponseWriter, r *http.Request) { return } -//TODO add err - amount_msat, _ := strconv.ParseInt(amount, 10, 64) + amount_msat, err := strconv.ParseInt(amount, 10, 64) + if err != nil { + log.Warn("amount is not a valid integer") + write_error(w) + return + } + amount_sat := amount_msat / 1000; -//TODO add err metadata := "[[\"text/identifier\",\"" + name + "@" + domain + "\"],[\"text/plain\",\"bolt card deposit\"]]" - pr, r_hash, _ := add_invoice(amount_sat, metadata) + pr, r_hash, err := add_invoice(amount_sat, metadata) + if err != nil { + log.Warn("could not add_invoice") + write_error(w) + return + } + + err = db_insert_receipt(card_id, pr, hex.EncodeToString(r_hash), amount_msat) + if err != nil { + log.Warn(err) + write_error(w) + return + } jsonData := []byte(`{` + `"status":"OK",` + diff --git a/lnurlp_request.go b/lnurlp_request.go index c9317d9..9e2aefb 100644 --- a/lnurlp_request.go +++ b/lnurlp_request.go @@ -28,7 +28,7 @@ func lnurlp_response(w http.ResponseWriter, r *http.Request) { // look up name in database (table cards, field card_name) - card_count, err := db_get_card_count_for_name(name) + card_count, err := db_get_card_count_for_name_enabled(name) if err != nil { log.Warn("could not get card count for name") write_error(w) @@ -36,7 +36,7 @@ func lnurlp_response(w http.ResponseWriter, r *http.Request) { } if card_count != 1 { - log.Info("not one card with that name") + log.Info("not one enabled card with that name") write_error(w) return }