create db/lnd/email packages
This commit is contained in:
parent
6153edd0c3
commit
9545e5bd4e
12 changed files with 255 additions and 736 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
@ -8,45 +8,45 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
type card struct {
|
type Card struct {
|
||||||
card_id int
|
Card_id int
|
||||||
card_guid string
|
Card_guid string
|
||||||
k0_auth_key string
|
K0_auth_key string
|
||||||
k1_decrypt_key string
|
K1_decrypt_key string
|
||||||
k2_cmac_key string
|
K2_cmac_key string
|
||||||
k3 string
|
K3 string
|
||||||
k4 string
|
K4 string
|
||||||
db_uid string
|
Db_uid string
|
||||||
last_counter_value uint32
|
Last_counter_value uint32
|
||||||
lnurlw_request_timeout_sec int
|
Lnurlw_request_timeout_sec int
|
||||||
lnurlw_enable string
|
Lnurlw_enable string
|
||||||
tx_limit_sats int
|
Tx_limit_sats int
|
||||||
day_limit_sats int
|
Day_limit_sats int
|
||||||
lnurlp_enable string
|
Lnurlp_enable string
|
||||||
email_address string
|
Email_address string
|
||||||
email_enable string
|
Email_enable string
|
||||||
uid_privacy string
|
Uid_privacy string
|
||||||
one_time_code string
|
One_time_code string
|
||||||
card_name string
|
Card_name string
|
||||||
allow_negative_balance string
|
Allow_negative_balance string
|
||||||
}
|
}
|
||||||
|
|
||||||
type payment struct {
|
type Payment struct {
|
||||||
card_payment_id int
|
Card_payment_id int
|
||||||
card_id int
|
Card_id int
|
||||||
lnurlw_k1 string
|
Lnurlw_k1 string
|
||||||
paid_flag string
|
Paid_flag string
|
||||||
}
|
}
|
||||||
|
|
||||||
type transaction struct {
|
type Transaction struct {
|
||||||
card_id int
|
Card_id int
|
||||||
tx_id int
|
Tx_id int
|
||||||
tx_type string
|
Tx_type string
|
||||||
tx_amount_msats int
|
Tx_amount_msats int
|
||||||
tx_time string
|
Tx_time string
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_open() (*sql.DB, error) {
|
func open() (*sql.DB, error) {
|
||||||
|
|
||||||
// get connection string from environment variables
|
// get connection string from environment variables
|
||||||
|
|
||||||
|
|
@ -65,11 +65,11 @@ func db_open() (*sql.DB, error) {
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_setting(setting_name string) string {
|
func Get_setting(setting_name string) string {
|
||||||
|
|
||||||
setting_value := ""
|
setting_value := ""
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
@ -86,11 +86,11 @@ func db_get_setting(setting_name string) string {
|
||||||
return setting_value
|
return setting_value
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_new_card(one_time_code string) (*card, error) {
|
func Get_new_card(one_time_code string) (*Card, error) {
|
||||||
|
|
||||||
c := card{}
|
c := Card{}
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &c, err
|
return &c, err
|
||||||
}
|
}
|
||||||
|
|
@ -101,12 +101,12 @@ func db_get_new_card(one_time_code string) (*card, error) {
|
||||||
` one_time_code_expiry > NOW() AND one_time_code_used = 'N' AND wiped = 'N';`
|
` one_time_code_expiry > NOW() AND one_time_code_used = 'N' AND wiped = 'N';`
|
||||||
row := db.QueryRow(sqlStatement, one_time_code)
|
row := db.QueryRow(sqlStatement, one_time_code)
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
&c.k0_auth_key,
|
&c.K0_auth_key,
|
||||||
&c.k2_cmac_key,
|
&c.K2_cmac_key,
|
||||||
&c.k3,
|
&c.K3,
|
||||||
&c.k4,
|
&c.K4,
|
||||||
&c.card_name,
|
&c.Card_name,
|
||||||
&c.uid_privacy)
|
&c.Uid_privacy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &c, err
|
return &c, err
|
||||||
}
|
}
|
||||||
|
|
@ -120,11 +120,11 @@ func db_get_new_card(one_time_code string) (*card, error) {
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_count_for_uid(uid string) (int, error) {
|
func Get_card_count_for_uid(uid string) (int, error) {
|
||||||
|
|
||||||
card_count := 0
|
card_count := 0
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -141,11 +141,11 @@ func db_get_card_count_for_uid(uid string) (int, error) {
|
||||||
return card_count, nil
|
return card_count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_count_for_name_lnurlp(name string) (int, error) {
|
func Get_card_count_for_name_lnurlp(name string) (int, error) {
|
||||||
|
|
||||||
card_count := 0
|
card_count := 0
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -162,11 +162,11 @@ func db_get_card_count_for_name_lnurlp(name string) (int, error) {
|
||||||
return card_count, nil
|
return card_count, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_id_for_name(name string) (int, error) {
|
func Get_card_id_for_name(name string) (int, error) {
|
||||||
|
|
||||||
card_id := 0
|
card_id := 0
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -183,10 +183,10 @@ func db_get_card_id_for_name(name string) (int, error) {
|
||||||
return card_id, nil
|
return card_id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_id_for_card_payment_id(card_payment_id int) (int, error) {
|
func Get_card_id_for_card_payment_id(card_payment_id int) (int, error) {
|
||||||
card_id := 0
|
card_id := 0
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -203,10 +203,10 @@ func db_get_card_id_for_card_payment_id(card_payment_id int) (int, error) {
|
||||||
return card_id, nil
|
return card_id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_id_for_r_hash(r_hash string) (int, error) {
|
func Get_card_id_for_r_hash(r_hash string) (int, error) {
|
||||||
card_id := 0
|
card_id := 0
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -223,11 +223,11 @@ func db_get_card_id_for_r_hash(r_hash string) (int, error) {
|
||||||
return card_id, nil
|
return card_id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_cards_blank_uid() ([]card, error) {
|
func Get_cards_blank_uid() ([]Card, error) {
|
||||||
|
|
||||||
// open the database
|
// open the database
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -249,12 +249,12 @@ func db_get_cards_blank_uid() ([]card, error) {
|
||||||
|
|
||||||
// prepare the results
|
// prepare the results
|
||||||
|
|
||||||
var cards []card
|
var cards []Card
|
||||||
|
|
||||||
// Loop through rows, using Scan to assign column data to struct fields.
|
// Loop through rows, using Scan to assign column data to struct fields.
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var c card
|
var c Card
|
||||||
err := rows.Scan(&c.card_id, &c.k2_cmac_key)
|
err := rows.Scan(&c.Card_id, &c.K2_cmac_key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cards, err
|
return cards, err
|
||||||
|
|
@ -271,8 +271,8 @@ func db_get_cards_blank_uid() ([]card, error) {
|
||||||
return cards, nil
|
return cards, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_update_card_uid_ctr(card_id int, uid string, ctr uint32) error {
|
func Update_card_uid_ctr(card_id int, uid string, ctr uint32) error {
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -294,11 +294,11 @@ func db_update_card_uid_ctr(card_id int, uid string, ctr uint32) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_from_uid(card_uid string) (*card, error) {
|
func Get_card_from_uid(card_uid string) (*Card, error) {
|
||||||
|
|
||||||
c := card{}
|
c := Card{}
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &c, err
|
return &c, err
|
||||||
}
|
}
|
||||||
|
|
@ -310,14 +310,14 @@ func db_get_card_from_uid(card_uid string) (*card, error) {
|
||||||
` FROM cards WHERE uid=$1 AND wiped='N';`
|
` FROM cards WHERE uid=$1 AND wiped='N';`
|
||||||
row := db.QueryRow(sqlStatement, card_uid)
|
row := db.QueryRow(sqlStatement, card_uid)
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
&c.card_id,
|
&c.Card_id,
|
||||||
&c.k2_cmac_key,
|
&c.K2_cmac_key,
|
||||||
&c.db_uid,
|
&c.Db_uid,
|
||||||
&c.last_counter_value,
|
&c.Last_counter_value,
|
||||||
&c.lnurlw_request_timeout_sec,
|
&c.Lnurlw_request_timeout_sec,
|
||||||
&c.lnurlw_enable,
|
&c.Lnurlw_enable,
|
||||||
&c.tx_limit_sats,
|
&c.Tx_limit_sats,
|
||||||
&c.day_limit_sats)
|
&c.Day_limit_sats)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &c, err
|
return &c, err
|
||||||
}
|
}
|
||||||
|
|
@ -325,11 +325,11 @@ func db_get_card_from_uid(card_uid string) (*card, error) {
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_from_card_id(card_id int) (*card, error) {
|
func Get_card_from_card_id(card_id int) (*Card, error) {
|
||||||
|
|
||||||
c := card{}
|
c := Card{}
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &c, err
|
return &c, err
|
||||||
}
|
}
|
||||||
|
|
@ -342,18 +342,18 @@ func db_get_card_from_card_id(card_id int) (*card, error) {
|
||||||
`allow_negative_balance FROM cards WHERE card_id=$1;`
|
`allow_negative_balance FROM cards WHERE card_id=$1;`
|
||||||
row := db.QueryRow(sqlStatement, card_id)
|
row := db.QueryRow(sqlStatement, card_id)
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
&c.card_id,
|
&c.Card_id,
|
||||||
&c.k2_cmac_key,
|
&c.K2_cmac_key,
|
||||||
&c.db_uid,
|
&c.Db_uid,
|
||||||
&c.last_counter_value,
|
&c.Last_counter_value,
|
||||||
&c.lnurlw_request_timeout_sec,
|
&c.Lnurlw_request_timeout_sec,
|
||||||
&c.lnurlw_enable,
|
&c.Lnurlw_enable,
|
||||||
&c.tx_limit_sats,
|
&c.Tx_limit_sats,
|
||||||
&c.day_limit_sats,
|
&c.Day_limit_sats,
|
||||||
&c.email_enable,
|
&c.Email_enable,
|
||||||
&c.email_address,
|
&c.Email_address,
|
||||||
&c.card_name,
|
&c.Card_name,
|
||||||
&c.allow_negative_balance)
|
&c.Allow_negative_balance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &c, err
|
return &c, err
|
||||||
}
|
}
|
||||||
|
|
@ -361,9 +361,9 @@ func db_get_card_from_card_id(card_id int) (*card, error) {
|
||||||
return &c, nil
|
return &c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_check_lnurlw_timeout(card_payment_id int) (bool, error) {
|
func Check_lnurlw_timeout(card_payment_id int) (bool, error) {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
|
@ -383,9 +383,9 @@ func db_check_lnurlw_timeout(card_payment_id int) (bool, error) {
|
||||||
return lnurlw_timeout, nil
|
return lnurlw_timeout, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_check_and_update_counter(card_id int, new_counter_value uint32) (bool, error) {
|
func Check_and_update_counter(card_id int, new_counter_value uint32) (bool, error) {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
@ -408,9 +408,9 @@ func db_check_and_update_counter(card_id int, new_counter_value uint32) (bool, e
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_insert_payment(card_id int, lnurlw_k1 string) error {
|
func Insert_payment(card_id int, lnurlw_k1 string) error {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -436,13 +436,13 @@ func db_insert_payment(card_id int, lnurlw_k1 string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_insert_receipt(
|
func Insert_receipt(
|
||||||
card_id int,
|
card_id int,
|
||||||
ln_invoice string,
|
ln_invoice string,
|
||||||
r_hash_hex string,
|
r_hash_hex string,
|
||||||
amount_msat int64) error {
|
amount_msat int64) error {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -468,8 +468,8 @@ func db_insert_receipt(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_update_receipt_state(r_hash_hex string, invoice_state string) error {
|
func Update_receipt_state(r_hash_hex string, invoice_state string) error {
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -493,10 +493,10 @@ func db_update_receipt_state(r_hash_hex string, invoice_state string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_payment_k1(lnurlw_k1 string) (*payment, error) {
|
func Get_payment_k1(lnurlw_k1 string) (*Payment, error) {
|
||||||
p := payment{}
|
p := Payment{}
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &p, err
|
return &p, err
|
||||||
}
|
}
|
||||||
|
|
@ -506,9 +506,9 @@ func db_get_payment_k1(lnurlw_k1 string) (*payment, error) {
|
||||||
` FROM card_payments WHERE lnurlw_k1=$1;`
|
` FROM card_payments WHERE lnurlw_k1=$1;`
|
||||||
row := db.QueryRow(sqlStatement, lnurlw_k1)
|
row := db.QueryRow(sqlStatement, lnurlw_k1)
|
||||||
err = row.Scan(
|
err = row.Scan(
|
||||||
&p.card_payment_id,
|
&p.Card_payment_id,
|
||||||
&p.card_id,
|
&p.Card_id,
|
||||||
&p.paid_flag)
|
&p.Paid_flag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &p, err
|
return &p, err
|
||||||
}
|
}
|
||||||
|
|
@ -516,9 +516,9 @@ func db_get_payment_k1(lnurlw_k1 string) (*payment, error) {
|
||||||
return &p, nil
|
return &p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_update_payment_invoice(card_payment_id int, ln_invoice string, amount_msats int64) error {
|
func Update_payment_invoice(card_payment_id int, ln_invoice string, amount_msats int64) error {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -540,9 +540,9 @@ func db_update_payment_invoice(card_payment_id int, ln_invoice string, amount_ms
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_update_payment_paid(card_payment_id int) error {
|
func Update_payment_paid(card_payment_id int) error {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -564,9 +564,9 @@ func db_update_payment_paid(card_payment_id int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_update_payment_status(card_payment_id int, payment_status string, failure_reason string) error {
|
func Update_payment_status(card_payment_id int, payment_status string, failure_reason string) error {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -596,9 +596,9 @@ func db_update_payment_status(card_payment_id int, payment_status string, failur
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_totals(card_id int) (int, error) {
|
func Get_card_totals(card_id int) (int, error) {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -620,10 +620,10 @@ func db_get_card_totals(card_id int) (int, error) {
|
||||||
return day_total_sats, nil
|
return day_total_sats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_txs(card_id int, max_txs int) ([]transaction, error) {
|
func Get_card_txs(card_id int, max_txs int) ([]Transaction, error) {
|
||||||
// open the database
|
// open the database
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -655,12 +655,12 @@ func db_get_card_txs(card_id int, max_txs int) ([]transaction, error) {
|
||||||
|
|
||||||
// prepare the results
|
// prepare the results
|
||||||
|
|
||||||
var transactions []transaction
|
var transactions []Transaction
|
||||||
|
|
||||||
// Loop through rows, using Scan to assign column data to struct fields.
|
// Loop through rows, using Scan to assign column data to struct fields.
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var t transaction
|
var t Transaction
|
||||||
err := rows.Scan(&t.card_id, &t.tx_id, &t.tx_type, &t.tx_amount_msats, &t.tx_time)
|
err := rows.Scan(&t.Card_id, &t.Tx_id, &t.Tx_type, &t.Tx_amount_msats, &t.Tx_time)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return transactions, err
|
return transactions, err
|
||||||
|
|
@ -677,9 +677,9 @@ func db_get_card_txs(card_id int, max_txs int) ([]transaction, error) {
|
||||||
return transactions, nil
|
return transactions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func db_get_card_total_sats(card_id int) (int, error) {
|
func Get_card_total_sats(card_id int) (int, error) {
|
||||||
|
|
||||||
db, err := db_open()
|
db, err := open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
|
@ -9,35 +9,36 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
func send_balance_email(recipient_email string, card_id int) {
|
func Send_balance_email(recipient_email string, card_id int) {
|
||||||
|
|
||||||
c, err := db_get_card_from_card_id(card_id)
|
c, err := db.Get_card_from_card_id(card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err.Error())
|
log.Warn(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
card_total_sats, err := db_get_card_total_sats(card_id)
|
card_total_sats, err := db.Get_card_total_sats(card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err.Error())
|
log.Warn(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
email_max_txs, err := strconv.Atoi(db_get_setting("EMAIL_MAX_TXS"))
|
email_max_txs, err := strconv.Atoi(db.Get_setting("EMAIL_MAX_TXS"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err.Error())
|
log.Warn(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
txs, err := db_get_card_txs(card_id, email_max_txs+1)
|
txs, err := db.Get_card_txs(card_id, email_max_txs+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err.Error())
|
log.Warn(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
subject := c.card_name + " balance = " + strconv.Itoa(card_total_sats) + " sats"
|
subject := c.Card_name + " balance = " + strconv.Itoa(card_total_sats) + " sats"
|
||||||
|
|
||||||
// add transactions to the email body
|
// add transactions to the email body
|
||||||
|
|
||||||
|
|
@ -56,9 +57,9 @@ func send_balance_email(recipient_email string, card_id int) {
|
||||||
if i < email_max_txs {
|
if i < email_max_txs {
|
||||||
html_body_sb.WriteString(
|
html_body_sb.WriteString(
|
||||||
"<tr>" +
|
"<tr>" +
|
||||||
"<td>" + tx.tx_time + "</td>" +
|
"<td>" + tx.Tx_time + "</td>" +
|
||||||
"<td>" + tx.tx_type + "</td>" +
|
"<td>" + tx.Tx_type + "</td>" +
|
||||||
"<td style='text-align:right'>" + strconv.Itoa(tx.tx_amount_msats/1000) + "</td>" +
|
"<td style='text-align:right'>" + strconv.Itoa(tx.Tx_amount_msats/1000) + "</td>" +
|
||||||
"</tr>")
|
"</tr>")
|
||||||
} else {
|
} else {
|
||||||
html_body_sb.WriteString(
|
html_body_sb.WriteString(
|
||||||
|
|
@ -69,8 +70,8 @@ func send_balance_email(recipient_email string, card_id int) {
|
||||||
"</tr>")
|
"</tr>")
|
||||||
}
|
}
|
||||||
|
|
||||||
text_body_sb.WriteString(tx.tx_type +
|
text_body_sb.WriteString(tx.Tx_type +
|
||||||
" " + strconv.Itoa(tx.tx_amount_msats/1000))
|
" " + strconv.Itoa(tx.Tx_amount_msats/1000))
|
||||||
}
|
}
|
||||||
|
|
||||||
html_body_sb.WriteString("</table></body></html>")
|
html_body_sb.WriteString("</table></body></html>")
|
||||||
|
|
@ -78,7 +79,7 @@ func send_balance_email(recipient_email string, card_id int) {
|
||||||
html_body := html_body_sb.String()
|
html_body := html_body_sb.String()
|
||||||
text_body := text_body_sb.String()
|
text_body := text_body_sb.String()
|
||||||
|
|
||||||
send_email(recipient_email,
|
Send_email(recipient_email,
|
||||||
subject,
|
subject,
|
||||||
html_body,
|
html_body,
|
||||||
text_body)
|
text_body)
|
||||||
|
|
@ -86,11 +87,11 @@ func send_balance_email(recipient_email string, card_id int) {
|
||||||
|
|
||||||
// https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/ses-example-send-email.html
|
// https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/ses-example-send-email.html
|
||||||
|
|
||||||
func send_email(recipient string, subject string, htmlBody string, textBody string) {
|
func Send_email(recipient string, subject string, htmlBody string, textBody string) {
|
||||||
|
|
||||||
aws_ses_id := db_get_setting("AWS_SES_ID")
|
aws_ses_id := db.Get_setting("AWS_SES_ID")
|
||||||
aws_ses_secret := db_get_setting("AWS_SES_SECRET")
|
aws_ses_secret := db.Get_setting("AWS_SES_SECRET")
|
||||||
sender := db_get_setting("AWS_SES_EMAIL_FROM")
|
sender := db.Get_setting("AWS_SES_EMAIL_FROM")
|
||||||
|
|
||||||
sess, err := session.NewSession(&aws.Config{
|
sess, err := session.NewSession(&aws.Config{
|
||||||
Region: aws.String("us-east-1"),
|
Region: aws.String("us-east-1"),
|
||||||
20
go.mod
20
go.mod
|
|
@ -16,9 +16,10 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||||
github.com/aead/siphash v1.0.1 // indirect
|
github.com/aead/siphash v1.0.1 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/btcsuite/btcd v0.23.4 // indirect
|
github.com/btcsuite/btcd v0.23.4 // indirect
|
||||||
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
|
||||||
|
|
@ -26,7 +27,6 @@ require (
|
||||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.6 // indirect
|
github.com/btcsuite/btcd/btcutil/psbt v1.1.6 // indirect
|
||||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect
|
||||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
|
||||||
github.com/btcsuite/btcutil v1.0.2 // indirect
|
|
||||||
github.com/btcsuite/btcwallet v0.16.4 // indirect
|
github.com/btcsuite/btcwallet v0.16.4 // indirect
|
||||||
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2 // indirect
|
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.2 // indirect
|
||||||
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0 // indirect
|
github.com/btcsuite/btcwallet/wallet/txrules v1.2.0 // indirect
|
||||||
|
|
@ -44,7 +44,6 @@ require (
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
|
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
|
||||||
github.com/decred/dcrd/lru v1.1.1 // indirect
|
github.com/decred/dcrd/lru v1.1.1 // indirect
|
||||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
|
||||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||||
github.com/dvyukov/go-fuzz v0.0.0-20220726122315-1d375ef9f9f6 // indirect
|
github.com/dvyukov/go-fuzz v0.0.0-20220726122315-1d375ef9f9f6 // indirect
|
||||||
github.com/fergusstrange/embedded-postgres v1.19.0 // indirect
|
github.com/fergusstrange/embedded-postgres v1.19.0 // indirect
|
||||||
|
|
@ -75,10 +74,7 @@ require (
|
||||||
github.com/jonboulle/clockwork v0.3.0 // indirect
|
github.com/jonboulle/clockwork v0.3.0 // indirect
|
||||||
github.com/jrick/logrotate v1.0.0 // indirect
|
github.com/jrick/logrotate v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/juju/loggo v1.0.0 // indirect
|
|
||||||
github.com/kkdai/bstream v1.0.0 // indirect
|
github.com/kkdai/bstream v1.0.0 // indirect
|
||||||
github.com/klauspost/compress v1.15.9 // indirect
|
|
||||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
|
||||||
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect
|
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect
|
||||||
github.com/lightninglabs/neutrino v0.14.2 // indirect
|
github.com/lightninglabs/neutrino v0.14.2 // indirect
|
||||||
github.com/lightningnetwork/lightning-onion v1.2.0 // indirect
|
github.com/lightningnetwork/lightning-onion v1.2.0 // indirect
|
||||||
|
|
@ -89,15 +85,11 @@ require (
|
||||||
github.com/lightningnetwork/lnd/ticker v1.1.0 // indirect
|
github.com/lightningnetwork/lnd/ticker v1.1.0 // indirect
|
||||||
github.com/lightningnetwork/lnd/tlv v1.0.3 // indirect
|
github.com/lightningnetwork/lnd/tlv v1.0.3 // indirect
|
||||||
github.com/lightningnetwork/lnd/tor v1.1.0 // indirect
|
github.com/lightningnetwork/lnd/tor v1.1.0 // indirect
|
||||||
github.com/lncm/lnd-rpc v1.0.2 // indirect
|
|
||||||
github.com/ltcsuite/ltcd v0.22.1-beta // indirect
|
github.com/ltcsuite/ltcd v0.22.1-beta // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mholt/archiver/v3 v3.5.1 // indirect
|
|
||||||
github.com/miekg/dns v1.1.50 // indirect
|
github.com/miekg/dns v1.1.50 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/nwaples/rardecode v1.1.3 // indirect
|
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||||
github.com/prometheus/client_model v0.3.0 // indirect
|
github.com/prometheus/client_model v0.3.0 // indirect
|
||||||
|
|
@ -110,7 +102,6 @@ require (
|
||||||
github.com/stretchr/testify v1.8.1 // indirect
|
github.com/stretchr/testify v1.8.1 // indirect
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect
|
||||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.6 // indirect
|
||||||
|
|
@ -121,18 +112,12 @@ require (
|
||||||
go.etcd.io/etcd/pkg/v3 v3.5.5 // indirect
|
go.etcd.io/etcd/pkg/v3 v3.5.5 // indirect
|
||||||
go.etcd.io/etcd/raft/v3 v3.5.5 // indirect
|
go.etcd.io/etcd/raft/v3 v3.5.5 // indirect
|
||||||
go.etcd.io/etcd/server/v3 v3.5.5 // indirect
|
go.etcd.io/etcd/server/v3 v3.5.5 // indirect
|
||||||
go.opentelemetry.io/contrib v1.9.0 // indirect
|
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect
|
||||||
go.opentelemetry.io/otel v1.11.1 // indirect
|
go.opentelemetry.io/otel v1.11.1 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect
|
|
||||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 // indirect
|
||||||
go.opentelemetry.io/otel/internal/metric v0.27.0 // indirect
|
|
||||||
go.opentelemetry.io/otel/metric v0.33.0 // indirect
|
|
||||||
go.opentelemetry.io/otel/sdk v1.11.1 // indirect
|
go.opentelemetry.io/otel/sdk v1.11.1 // indirect
|
||||||
go.opentelemetry.io/otel/sdk/export/metric v0.28.0 // indirect
|
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.33.0 // indirect
|
|
||||||
go.opentelemetry.io/otel/trace v1.11.1 // indirect
|
go.opentelemetry.io/otel/trace v1.11.1 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
|
|
@ -146,7 +131,6 @@ require (
|
||||||
golang.org/x/text v0.4.0 // indirect
|
golang.org/x/text v0.4.0 // indirect
|
||||||
golang.org/x/time v0.2.0 // indirect
|
golang.org/x/time v0.2.0 // indirect
|
||||||
golang.org/x/tools v0.3.0 // indirect
|
golang.org/x/tools v0.3.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
|
|
||||||
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect
|
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
gopkg.in/errgo.v1 v1.0.1 // indirect
|
gopkg.in/errgo.v1 v1.0.1 // indirect
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package lnd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
@ -20,6 +20,9 @@ import (
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
|
||||||
"gopkg.in/macaroon.v2"
|
"gopkg.in/macaroon.v2"
|
||||||
|
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
|
"github.com/boltcard/boltcard/email"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rpcCreds map[string]string
|
type rpcCreds map[string]string
|
||||||
|
|
@ -72,9 +75,9 @@ func getGrpcConn(hostname string, port int, tlsFile, macaroonFile string) *grpc.
|
||||||
|
|
||||||
// https://api.lightning.community/?shell#addinvoice
|
// https://api.lightning.community/?shell#addinvoice
|
||||||
|
|
||||||
func add_invoice(amount_sat int64, metadata string) (payment_request string, r_hash []byte, return_err error) {
|
func Add_invoice(amount_sat int64, metadata string) (payment_request string, r_hash []byte, return_err error) {
|
||||||
|
|
||||||
ln_port, err := strconv.Atoi(db_get_setting("LN_PORT"))
|
ln_port, err := strconv.Atoi(db.Get_setting("LN_PORT"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -82,10 +85,10 @@ func add_invoice(amount_sat int64, metadata string) (payment_request string, r_h
|
||||||
dh := sha256.Sum256([]byte(metadata))
|
dh := sha256.Sum256([]byte(metadata))
|
||||||
|
|
||||||
connection := getGrpcConn(
|
connection := getGrpcConn(
|
||||||
db_get_setting("LN_HOST"),
|
db.Get_setting("LN_HOST"),
|
||||||
ln_port,
|
ln_port,
|
||||||
db_get_setting("LN_TLS_FILE"),
|
db.Get_setting("LN_TLS_FILE"),
|
||||||
db_get_setting("LN_MACAROON_FILE"))
|
db.Get_setting("LN_MACAROON_FILE"))
|
||||||
|
|
||||||
l_client := lnrpc.NewLightningClient(connection)
|
l_client := lnrpc.NewLightningClient(connection)
|
||||||
|
|
||||||
|
|
@ -106,23 +109,23 @@ func add_invoice(amount_sat int64, metadata string) (payment_request string, r_h
|
||||||
|
|
||||||
// https://api.lightning.community/?shell#subscribesingleinvoice
|
// https://api.lightning.community/?shell#subscribesingleinvoice
|
||||||
|
|
||||||
func monitor_invoice_state(r_hash []byte) {
|
func Monitor_invoice_state(r_hash []byte) {
|
||||||
|
|
||||||
// SubscribeSingleInvoice
|
// SubscribeSingleInvoice
|
||||||
|
|
||||||
// get node parameters from environment variables
|
// get node parameters from environment variables
|
||||||
|
|
||||||
ln_port, err := strconv.Atoi(db_get_setting("LN_PORT"))
|
ln_port, err := strconv.Atoi(db.Get_setting("LN_PORT"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
connection := getGrpcConn(
|
connection := getGrpcConn(
|
||||||
db_get_setting("LN_HOST"),
|
db.Get_setting("LN_HOST"),
|
||||||
ln_port,
|
ln_port,
|
||||||
db_get_setting("LN_TLS_FILE"),
|
db.Get_setting("LN_TLS_FILE"),
|
||||||
db_get_setting("LN_MACAROON_FILE"))
|
db.Get_setting("LN_MACAROON_FILE"))
|
||||||
|
|
||||||
i_client := invoicesrpc.NewInvoicesClient(connection)
|
i_client := invoicesrpc.NewInvoicesClient(connection)
|
||||||
|
|
||||||
|
|
@ -156,14 +159,14 @@ func monitor_invoice_state(r_hash []byte) {
|
||||||
"invoice_state": invoice_state,
|
"invoice_state": invoice_state,
|
||||||
}).Info("invoice state updated")
|
}).Info("invoice state updated")
|
||||||
|
|
||||||
db_update_receipt_state(hex.EncodeToString(r_hash), invoice_state)
|
db.Update_receipt_state(hex.EncodeToString(r_hash), invoice_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.Close()
|
connection.Close()
|
||||||
|
|
||||||
// send email
|
// send email
|
||||||
|
|
||||||
card_id, err := db_get_card_id_for_r_hash(hex.EncodeToString(r_hash))
|
card_id, err := db.Get_card_id_for_r_hash(hex.EncodeToString(r_hash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"r_hash": hex.EncodeToString(r_hash)}).Warn(err)
|
log.WithFields(log.Fields{"r_hash": hex.EncodeToString(r_hash)}).Warn(err)
|
||||||
return
|
return
|
||||||
|
|
@ -171,52 +174,52 @@ func monitor_invoice_state(r_hash []byte) {
|
||||||
|
|
||||||
log.WithFields(log.Fields{"r_hash": hex.EncodeToString(r_hash), "card_id": card_id}).Debug("card found")
|
log.WithFields(log.Fields{"r_hash": hex.EncodeToString(r_hash), "card_id": card_id}).Debug("card found")
|
||||||
|
|
||||||
c, err := db_get_card_from_card_id(card_id)
|
c, err := db.Get_card_from_card_id(card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"r_hash": hex.EncodeToString(r_hash)}).Warn(err)
|
log.WithFields(log.Fields{"r_hash": hex.EncodeToString(r_hash)}).Warn(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.email_enable != "Y" {
|
if c.Email_enable != "Y" {
|
||||||
log.Debug("email is not enabled for the card")
|
log.Debug("email is not enabled for the card")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go send_balance_email(c.email_address, card_id)
|
go email.Send_balance_email(c.Email_address, card_id)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://api.lightning.community/?shell#sendpaymentv2
|
// https://api.lightning.community/?shell#sendpaymentv2
|
||||||
|
|
||||||
func pay_invoice(card_payment_id int, invoice string) {
|
func Pay_invoice(card_payment_id int, invoice string) {
|
||||||
|
|
||||||
// SendPaymentV2
|
// SendPaymentV2
|
||||||
|
|
||||||
// get node parameters from environment variables
|
// get node parameters from environment variables
|
||||||
|
|
||||||
ln_port, err := strconv.Atoi(db_get_setting("LN_PORT"))
|
ln_port, err := strconv.Atoi(db.Get_setting("LN_PORT"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
connection := getGrpcConn(
|
connection := getGrpcConn(
|
||||||
db_get_setting("LN_HOST"),
|
db.Get_setting("LN_HOST"),
|
||||||
ln_port,
|
ln_port,
|
||||||
db_get_setting("LN_TLS_FILE"),
|
db.Get_setting("LN_TLS_FILE"),
|
||||||
db_get_setting("LN_MACAROON_FILE"))
|
db.Get_setting("LN_MACAROON_FILE"))
|
||||||
|
|
||||||
r_client := routerrpc.NewRouterClient(connection)
|
r_client := routerrpc.NewRouterClient(connection)
|
||||||
|
|
||||||
fee_limit_sat_str := db_get_setting("FEE_LIMIT_SAT")
|
fee_limit_sat_str := db.Get_setting("FEE_LIMIT_SAT")
|
||||||
fee_limit_sat, err := strconv.ParseInt(fee_limit_sat_str, 10, 64)
|
fee_limit_sat, err := strconv.ParseInt(fee_limit_sat_str, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fee_limit_percent_str := db_get_setting("FEE_LIMIT_PERCENT")
|
fee_limit_percent_str := db.Get_setting("FEE_LIMIT_PERCENT")
|
||||||
fee_limit_percent, err := strconv.ParseFloat(fee_limit_percent_str, 64)
|
fee_limit_percent, err := strconv.ParseFloat(fee_limit_percent_str, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
||||||
|
|
@ -260,7 +263,7 @@ func pay_invoice(card_payment_id int, invoice string) {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Info("payment failure reason : ", failure_reason)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Info("payment failure reason : ", failure_reason)
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Info("payment status : ", payment_status)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Info("payment status : ", payment_status)
|
||||||
|
|
||||||
err = db_update_payment_status(card_payment_id, payment_status, failure_reason)
|
err = db.Update_payment_status(card_payment_id, payment_status, failure_reason)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
||||||
return
|
return
|
||||||
|
|
@ -271,7 +274,7 @@ func pay_invoice(card_payment_id int, invoice string) {
|
||||||
|
|
||||||
// send email
|
// send email
|
||||||
|
|
||||||
card_id, err := db_get_card_id_for_card_payment_id(card_payment_id)
|
card_id, err := db.Get_card_id_for_card_payment_id(card_payment_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
||||||
return
|
return
|
||||||
|
|
@ -279,18 +282,18 @@ func pay_invoice(card_payment_id int, invoice string) {
|
||||||
|
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id, "card_id": card_id}).Debug("card found")
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id, "card_id": card_id}).Debug("card found")
|
||||||
|
|
||||||
c, err := db_get_card_from_card_id(card_id)
|
c, err := db.Get_card_from_card_id(card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": card_payment_id}).Warn(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.email_enable != "Y" {
|
if c.Email_enable != "Y" {
|
||||||
log.Debug("email is not enabled for the card")
|
log.Debug("email is not enabled for the card")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go send_balance_email(c.email_address, card_id)
|
go email.Send_balance_email(c.Email_address, card_id)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -6,10 +6,12 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"github.com/boltcard/boltcard/lnd"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
||||||
if db_get_setting("FUNCTION_LNURLP") != "ENABLE" {
|
if db.Get_setting("FUNCTION_LNURLP") != "ENABLE" {
|
||||||
log.Debug("LNURLp function is not enabled")
|
log.Debug("LNURLp function is not enabled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -17,7 +19,7 @@ func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
||||||
name := mux.Vars(r)["name"]
|
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)
|
card_id, err := db.Get_card_id_for_name(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("card name not found")
|
log.Info("card name not found")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
@ -33,7 +35,7 @@ func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
||||||
"req.Host": r.Host,
|
"req.Host": r.Host,
|
||||||
}).Info("lnurlp_callback")
|
}).Info("lnurlp_callback")
|
||||||
|
|
||||||
domain := db_get_setting("HOST_DOMAIN")
|
domain := db.Get_setting("HOST_DOMAIN")
|
||||||
if r.Host != domain {
|
if r.Host != domain {
|
||||||
log.Warn("wrong host domain")
|
log.Warn("wrong host domain")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
@ -50,21 +52,21 @@ func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
||||||
amount_sat := amount_msat / 1000
|
amount_sat := amount_msat / 1000
|
||||||
|
|
||||||
metadata := "[[\"text/identifier\",\"" + name + "@" + domain + "\"],[\"text/plain\",\"bolt card deposit\"]]"
|
metadata := "[[\"text/identifier\",\"" + name + "@" + domain + "\"],[\"text/plain\",\"bolt card deposit\"]]"
|
||||||
pr, r_hash, err := add_invoice(amount_sat, metadata)
|
pr, r_hash, err := lnd.Add_invoice(amount_sat, metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("could not add_invoice")
|
log.Warn("could not add_invoice")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = db_insert_receipt(card_id, pr, hex.EncodeToString(r_hash), amount_msat)
|
err = db.Insert_receipt(card_id, pr, hex.EncodeToString(r_hash), amount_msat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go monitor_invoice_state(r_hash)
|
go lnd.Monitor_invoice_state(r_hash)
|
||||||
|
|
||||||
log.Debug("sending 'status OK' response")
|
log.Debug("sending 'status OK' response")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,11 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
||||||
if db_get_setting("FUNCTION_LNURLP") != "ENABLE" {
|
if db.Get_setting("FUNCTION_LNURLP") != "ENABLE" {
|
||||||
log.Debug("LNURLp function is not enabled")
|
log.Debug("LNURLp function is not enabled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +24,7 @@ func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// look up domain setting (HOST_DOMAIN)
|
// look up domain setting (HOST_DOMAIN)
|
||||||
|
|
||||||
domain := db_get_setting("HOST_DOMAIN")
|
domain := db.Get_setting("HOST_DOMAIN")
|
||||||
if r.Host != domain {
|
if r.Host != domain {
|
||||||
log.Warn("wrong host domain")
|
log.Warn("wrong host domain")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
@ -32,7 +33,7 @@ func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// look up name in database (table cards, field card_name)
|
// look up name in database (table cards, field card_name)
|
||||||
|
|
||||||
card_count, err := db_get_card_count_for_name_lnurlp(name)
|
card_count, err := db.Get_card_count_for_name_lnurlp(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("could not get card count for name")
|
log.Warn("could not get card count for name")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@ import (
|
||||||
decodepay "github.com/fiatjaf/ln-decodepay"
|
decodepay "github.com/fiatjaf/ln-decodepay"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
|
"github.com/boltcard/boltcard/lnd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
env_host_domain := db_get_setting("HOST_DOMAIN")
|
env_host_domain := db.Get_setting("HOST_DOMAIN")
|
||||||
if req.Host != env_host_domain {
|
if req.Host != env_host_domain {
|
||||||
log.Warn("wrong host domain")
|
log.Warn("wrong host domain")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
@ -29,7 +31,7 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
param_k1 := params_k1[0]
|
param_k1 := params_k1[0]
|
||||||
|
|
||||||
p, err := db_get_payment_k1(param_k1)
|
p, err := db.Get_payment_k1(param_k1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"url": url, "k1": param_k1}).Warn(err)
|
log.WithFields(log.Fields{"url": url, "k1": param_k1}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
@ -37,28 +39,28 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that payment has not been made
|
// check that payment has not been made
|
||||||
if p.paid_flag != "N" {
|
if p.Paid_flag != "N" {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("payment already made")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("payment already made")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if lnurlw_request has timed out
|
// check if lnurlw_request has timed out
|
||||||
lnurlw_timeout, err := db_check_lnurlw_timeout(p.card_payment_id)
|
lnurlw_timeout, err := db.Check_lnurlw_timeout(p.Card_payment_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if lnurlw_timeout == true {
|
if lnurlw_timeout == true {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("lnurlw request has timed out")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("lnurlw request has timed out")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
params_pr, ok := req.URL.Query()["pr"]
|
params_pr, ok := req.URL.Query()["pr"]
|
||||||
if !ok || len(params_pr[0]) < 1 {
|
if !ok || len(params_pr[0]) < 1 {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn("pr field not found")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn("pr field not found")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -67,19 +69,19 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
bolt11, _ := decodepay.Decodepay(param_pr)
|
bolt11, _ := decodepay.Decodepay(param_pr)
|
||||||
|
|
||||||
// record the lightning invoice
|
// record the lightning invoice
|
||||||
err = db_update_payment_invoice(p.card_payment_id, param_pr, bolt11.MSatoshi)
|
err = db.Update_payment_invoice(p.Card_payment_id, param_pr, bolt11.MSatoshi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Debug("checking payment rules")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Debug("checking payment rules")
|
||||||
|
|
||||||
// check if we are only sending funds to a defined test node
|
// check if we are only sending funds to a defined test node
|
||||||
testnode := db_get_setting("LN_TESTNODE")
|
testnode := db.Get_setting("LN_TESTNODE")
|
||||||
if testnode != "" && bolt11.Payee != testnode {
|
if testnode != "" && bolt11.Payee != testnode {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("rejected as not the defined test node")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("rejected as not the defined test node")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -88,33 +90,33 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
invoice_sats := int(bolt11.MSatoshi / 1000)
|
invoice_sats := int(bolt11.MSatoshi / 1000)
|
||||||
|
|
||||||
day_total_sats, err := db_get_card_totals(p.card_id)
|
day_total_sats, err := db.Get_card_totals(p.Card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := db_get_card_from_card_id(p.card_id)
|
c, err := db.Get_card_from_card_id(p.Card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if invoice_sats > c.tx_limit_sats {
|
if invoice_sats > c.Tx_limit_sats {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("invoice_sats: ", invoice_sats)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("invoice_sats: ", invoice_sats)
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("tx_limit_sats: ", c.tx_limit_sats)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("tx_limit_sats: ", c.Tx_limit_sats)
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("over tx_limit_sats!")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("over tx_limit_sats!")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if day_total_sats+invoice_sats > c.day_limit_sats {
|
if day_total_sats+invoice_sats > c.Day_limit_sats {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("invoice_sats: ", invoice_sats)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("invoice_sats: ", invoice_sats)
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("day_total_sats: ", day_total_sats)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("day_total_sats: ", day_total_sats)
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("day_limit_sats: ", c.day_limit_sats)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("day_limit_sats: ", c.Day_limit_sats)
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("over day_limit_sats!")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("over day_limit_sats!")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -122,27 +124,27 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
// check the card balance if marked as 'must stay above zero' (default)
|
// check the card balance if marked as 'must stay above zero' (default)
|
||||||
// i.e. cards.allow_negative_balance == 'N'
|
// i.e. cards.allow_negative_balance == 'N'
|
||||||
|
|
||||||
if c.allow_negative_balance != "Y" {
|
if c.Allow_negative_balance != "Y" {
|
||||||
card_total, err := db_get_card_total_sats(p.card_id)
|
card_total, err := db.Get_card_total_sats(p.Card_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if card_total-invoice_sats < 0 {
|
if card_total-invoice_sats < 0 {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn("not enough balance")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn("not enough balance")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Info("paying invoice")
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Info("paying invoice")
|
||||||
|
|
||||||
// update paid_flag so we only attempt payment once
|
// update paid_flag so we only attempt payment once
|
||||||
err = db_update_payment_paid(p.card_payment_id)
|
err = db.Update_payment_paid(p.Card_payment_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"card_payment_id": p.card_payment_id}).Warn(err)
|
log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err)
|
||||||
write_error(w)
|
write_error(w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +155,7 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
// {"status": "ERROR", "reason": "error details..."}
|
// {"status": "ERROR", "reason": "error details..."}
|
||||||
// JSON response and then attempts to pay the invoices asynchronously.
|
// JSON response and then attempts to pay the invoices asynchronously.
|
||||||
|
|
||||||
go pay_invoice(p.card_payment_id, param_pr)
|
go lnd.Pay_invoice(p.Card_payment_id, param_pr)
|
||||||
|
|
||||||
log.Debug("sending 'status OK' response")
|
log.Debug("sending 'status OK' response")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
|
|
@ -74,10 +75,10 @@ func setup_card_record(uid string, ctr uint32, uid_bin []byte, ctr_bin []byte, c
|
||||||
// find the card record by matching the cmac
|
// find the card record by matching the cmac
|
||||||
// get possible card records from the database
|
// get possible card records from the database
|
||||||
|
|
||||||
cards, err := db_get_cards_blank_uid()
|
cards, err := db.Get_cards_blank_uid()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("db_get_cards_blank_uid errored")
|
return errors.New("db.Get_cards_blank_uid errored")
|
||||||
}
|
}
|
||||||
|
|
||||||
// check card records for a matching cmac
|
// check card records for a matching cmac
|
||||||
|
|
@ -85,7 +86,7 @@ func setup_card_record(uid string, ctr uint32, uid_bin []byte, ctr_bin []byte, c
|
||||||
for i, card := range cards {
|
for i, card := range cards {
|
||||||
// check the cmac
|
// check the cmac
|
||||||
|
|
||||||
k2_cmac_key, err := hex.DecodeString(card.k2_cmac_key)
|
k2_cmac_key, err := hex.DecodeString(card.K2_cmac_key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("card.k2_cmac_key decode failed")
|
return errors.New("card.k2_cmac_key decode failed")
|
||||||
|
|
@ -100,12 +101,12 @@ func setup_card_record(uid string, ctr uint32, uid_bin []byte, ctr_bin []byte, c
|
||||||
if cmac_valid == true {
|
if cmac_valid == true {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"i": i,
|
"i": i,
|
||||||
"card.card_id": card.card_id,
|
"card.card_id": card.Card_id,
|
||||||
"card.k2_cmac_key": card.k2_cmac_key,
|
"card.k2_cmac_key": card.K2_cmac_key,
|
||||||
}).Info("cmac match found")
|
}).Info("cmac match found")
|
||||||
|
|
||||||
// store the uid and ctr in the card record
|
// store the uid and ctr in the card record
|
||||||
err := db_update_card_uid_ctr(card.card_id, uid, ctr)
|
err := db.Update_card_uid_ctr(card.Card_id, uid, ctr)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -150,7 +151,7 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
// decrypt p with aes_decrypt_key
|
// decrypt p with aes_decrypt_key
|
||||||
|
|
||||||
aes_decrypt_key := db_get_setting("AES_DECRYPT_KEY")
|
aes_decrypt_key := db.Get_setting("AES_DECRYPT_KEY")
|
||||||
|
|
||||||
key_sdm_file_read, err := hex.DecodeString(aes_decrypt_key)
|
key_sdm_file_read, err := hex.DecodeString(aes_decrypt_key)
|
||||||
|
|
||||||
|
|
@ -179,7 +180,7 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
log.WithFields(log.Fields{"uid": uid_str, "ctr": ctr_int}).Info("decrypted card data")
|
log.WithFields(log.Fields{"uid": uid_str, "ctr": ctr_int}).Info("decrypted card data")
|
||||||
|
|
||||||
card_count, err := db_get_card_count_for_uid(uid_str)
|
card_count, err := db.Get_card_count_for_uid(uid_str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.New("could not get card count for uid")
|
return 0, errors.New("could not get card count for uid")
|
||||||
|
|
@ -197,7 +198,7 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
// get card record from database for UID
|
// get card record from database for UID
|
||||||
|
|
||||||
c, err := db_get_card_from_uid(uid_str)
|
c, err := db.Get_card_from_uid(uid_str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errors.New("card not found for uid")
|
return 0, errors.New("card not found for uid")
|
||||||
|
|
@ -205,13 +206,13 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
// check if card is enabled
|
// check if card is enabled
|
||||||
|
|
||||||
if c.lnurlw_enable != "Y" {
|
if c.Lnurlw_enable != "Y" {
|
||||||
return 0, errors.New("card lnurlw enable is not set to Y")
|
return 0, errors.New("card lnurlw enable is not set to Y")
|
||||||
}
|
}
|
||||||
|
|
||||||
// check cmac
|
// check cmac
|
||||||
|
|
||||||
k2_cmac_key, err := hex.DecodeString(c.k2_cmac_key)
|
k2_cmac_key, err := hex.DecodeString(c.K2_cmac_key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
@ -229,7 +230,7 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
// check and update last_counter_value
|
// check and update last_counter_value
|
||||||
|
|
||||||
counter_ok, err := db_check_and_update_counter(c.card_id, ctr_int)
|
counter_ok, err := db.Check_and_update_counter(c.Card_id, ctr_int)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
@ -239,14 +240,14 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
return 0, errors.New("counter not increasing")
|
return 0, errors.New("counter not increasing")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{"card_id": c.card_id, "counter": ctr_int}).Info("validated")
|
log.WithFields(log.Fields{"card_id": c.Card_id, "counter": ctr_int}).Info("validated")
|
||||||
|
|
||||||
return c.card_id, nil
|
return c.Card_id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
env_host_domain := db_get_setting("HOST_DOMAIN")
|
env_host_domain := db.Get_setting("HOST_DOMAIN")
|
||||||
if req.Host != env_host_domain {
|
if req.Host != env_host_domain {
|
||||||
log.Warn("wrong host domain")
|
log.Warn("wrong host domain")
|
||||||
write_error(w)
|
write_error(w)
|
||||||
|
|
@ -271,7 +272,7 @@ func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
// store k1 in database and include in response
|
// store k1 in database and include in response
|
||||||
|
|
||||||
err = db_insert_payment(card_id, lnurlw_k1)
|
err = db.Insert_payment(card_id, lnurlw_k1)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err.Error())
|
log.Warn(err.Error())
|
||||||
|
|
@ -286,7 +287,7 @@ func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
||||||
lnurlw_cb_url = "https://" + req.Host + "/cb"
|
lnurlw_cb_url = "https://" + req.Host + "/cb"
|
||||||
}
|
}
|
||||||
|
|
||||||
min_withdraw_sats_str := db_get_setting("MIN_WITHDRAW_SATS")
|
min_withdraw_sats_str := db.Get_setting("MIN_WITHDRAW_SATS")
|
||||||
min_withdraw_sats, err := strconv.Atoi(min_withdraw_sats_str)
|
min_withdraw_sats, err := strconv.Atoi(min_withdraw_sats_str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -295,7 +296,7 @@ func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
max_withdraw_sats_str := db_get_setting("MAX_WITHDRAW_SATS")
|
max_withdraw_sats_str := db.Get_setting("MAX_WITHDRAW_SATS")
|
||||||
max_withdraw_sats, err := strconv.Atoi(max_withdraw_sats_str)
|
max_withdraw_sats, err := strconv.Atoi(max_withdraw_sats_str)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
5
main.go
5
main.go
|
|
@ -5,6 +5,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
var router = mux.NewRouter()
|
var router = mux.NewRouter()
|
||||||
|
|
@ -24,7 +25,7 @@ func write_error_message(w http.ResponseWriter, message string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log_level := db_get_setting("LOG_LEVEL")
|
log_level := db.Get_setting("LOG_LEVEL")
|
||||||
|
|
||||||
switch log_level {
|
switch log_level {
|
||||||
case "DEBUG":
|
case "DEBUG":
|
||||||
|
|
@ -50,7 +51,7 @@ func main() {
|
||||||
router.Path("/.well-known/lnurlp/{name}").Methods("GET").HandlerFunc(lnurlp_response)
|
router.Path("/.well-known/lnurlp/{name}").Methods("GET").HandlerFunc(lnurlp_response)
|
||||||
router.Path("/lnurlp/{name}").Methods("GET").HandlerFunc(lnurlp_callback)
|
router.Path("/lnurlp/{name}").Methods("GET").HandlerFunc(lnurlp_callback)
|
||||||
|
|
||||||
port := db_get_setting("HOST_PORT")
|
port := db.Get_setting("HOST_PORT")
|
||||||
if port == "" {
|
if port == "" {
|
||||||
port = "9000"
|
port = "9000"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"github.com/boltcard/boltcard/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,7 +56,7 @@ func new_card_request(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
lnurlw_base := "lnurlw://" + req.Host + "/ln"
|
lnurlw_base := "lnurlw://" + req.Host + "/ln"
|
||||||
|
|
||||||
c, err := db_get_new_card(a)
|
c, err := db.Get_new_card(a)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
log.Debug(err)
|
log.Debug(err)
|
||||||
|
|
@ -69,19 +70,19 @@ func new_card_request(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
k1_decrypt_key := db_get_setting("AES_DECRYPT_KEY")
|
k1_decrypt_key := db.Get_setting("AES_DECRYPT_KEY")
|
||||||
|
|
||||||
response := NewCardResponse{}
|
response := NewCardResponse{}
|
||||||
response.PROTOCOL_NAME = "create_bolt_card_response"
|
response.PROTOCOL_NAME = "create_bolt_card_response"
|
||||||
response.PROTOCOL_VERSION = 2
|
response.PROTOCOL_VERSION = 2
|
||||||
response.CARD_NAME = c.card_name
|
response.CARD_NAME = c.Card_name
|
||||||
response.LNURLW_BASE = lnurlw_base
|
response.LNURLW_BASE = lnurlw_base
|
||||||
response.K0 = c.k0_auth_key
|
response.K0 = c.K0_auth_key
|
||||||
response.K1 = k1_decrypt_key
|
response.K1 = k1_decrypt_key
|
||||||
response.K2 = c.k2_cmac_key
|
response.K2 = c.K2_cmac_key
|
||||||
response.K3 = c.k3
|
response.K3 = c.K3
|
||||||
response.K4 = c.k4
|
response.K4 = c.K4
|
||||||
response.UID_PRIVACY = c.uid_privacy
|
response.UID_PRIVACY = c.Uid_privacy
|
||||||
|
|
||||||
log.SetFormatter(&log.JSONFormatter{
|
log.SetFormatter(&log.JSONFormatter{
|
||||||
DisableHTMLEscape: true,
|
DisableHTMLEscape: true,
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,5 @@ INSERT INTO settings (name, value) VALUES ('AWS_SES_ID', '');
|
||||||
INSERT INTO settings (name, value) VALUES ('AWS_SES_SECRET', '');
|
INSERT INTO settings (name, value) VALUES ('AWS_SES_SECRET', '');
|
||||||
INSERT INTO settings (name, value) VALUES ('AWS_SES_EMAIL_FROM', '');
|
INSERT INTO settings (name, value) VALUES ('AWS_SES_EMAIL_FROM', '');
|
||||||
INSERT INTO settings (name, value) VALUES ('EMAIL_MAX_TXS', '');
|
INSERT INTO settings (name, value) VALUES ('EMAIL_MAX_TXS', '');
|
||||||
|
INSERT INTO settings (name, value) VALUES ('FUNCTION_LNDHUB', '');
|
||||||
|
INSERT INTO settings (name, value) VALUES ('LNDHUB_URL', '');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue