From b76252d6ef240d3f5694b4ffdb8ab846232dab49 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Thu, 29 Jun 2023 19:34:18 +0000 Subject: [PATCH 1/7] create & update card pin details --- db/db.go | 29 +++++++++++++++++++++-------- internalapi/createboltcard.go | 25 +++++++++++++++++++++++-- internalapi/updateboltcard.go | 25 +++++++++++++++++++++++-- script/s_create_db | 2 +- sql/create_db.sql | 3 +++ 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/db/db.go b/db/db.go index fb5e8ca..41a7d29 100644 --- a/db/db.go +++ b/db/db.go @@ -773,7 +773,7 @@ func Get_card_name_count(card_name string) (card_count int, err error) { func Insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string, k3 string, k4 string, tx_limit_sats int, day_limit_sats int, lnurlw_enable bool, card_name string, uid_privacy bool, - allow_neg_bal_ptr bool) error { + allow_neg_bal_ptr bool, pin_enable bool, pin_number string, pin_limit_sats int) error { lnurlw_enable_yn := "N" if lnurlw_enable { @@ -790,6 +790,11 @@ func Insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string, k allow_neg_bal_yn = "Y" } + pin_enable_yn := "N" + if pin_enable { + pin_enable_yn = "Y" + } + db, err := open() if err != nil { return err @@ -811,11 +816,12 @@ func Insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string, k sqlStatement = `INSERT INTO cards` + ` (one_time_code, k0_auth_key, k2_cmac_key, k3, k4, uid, last_counter_value,` + ` lnurlw_request_timeout_sec, tx_limit_sats, day_limit_sats, lnurlw_enable,` + - ` one_time_code_used, card_name, uid_privacy, allow_negative_balance)` + - ` VALUES ($1, $2, $3, $4, $5, '', 0, 60, $6, $7, $8, 'N', $9, $10, $11);` + ` one_time_code_used, card_name, uid_privacy, allow_negative_balance,` + + ` pin_enable, pin_number, pin_limit_sats)` + + ` VALUES ($1, $2, $3, $4, $5, '', 0, 60, $6, $7, $8, 'N', $9, $10, $11, $12, $13, $14);` res, err = db.Exec(sqlStatement, one_time_code, k0_auth_key, k2_cmac_key, k3, k4, tx_limit_sats, day_limit_sats, lnurlw_enable_yn, card_name, uid_privacy_yn, - allow_neg_bal_yn) + allow_neg_bal_yn, pin_enable_yn, pin_number, pin_limit_sats) if err != nil { return err } @@ -871,13 +877,19 @@ func Wipe_card(card_name string) (*Card_wipe_info, error) { return &card_wipe_info, nil } -func Update_card(card_name string, lnurlw_enable bool, tx_limit_sats int, day_limit_sats int) error { +func Update_card(card_name string, lnurlw_enable bool, tx_limit_sats int, day_limit_sats int, + pin_enable bool, pin_number string, pin_limit_sats int) error { lnurlw_enable_yn := "N" if lnurlw_enable { lnurlw_enable_yn = "Y" } + pin_enable_yn := "N" + if pin_enable { + pin_enable_yn = "Y" + } + db, err := open() if err != nil { @@ -886,10 +898,11 @@ func Update_card(card_name string, lnurlw_enable bool, tx_limit_sats int, day_li defer db.Close() - sqlStatement := `UPDATE cards SET lnurlw_enable = $2, tx_limit_sats = $3, day_limit_sats = $4 ` + - `WHERE card_name = $1 AND wiped = 'N';` + sqlStatement := `UPDATE cards SET lnurlw_enable = $2, tx_limit_sats = $3, day_limit_sats = $4, ` + + `pin_enable = $5, pin_number = $6, pin_limit_sats = $7 WHERE card_name = $1 AND wiped = 'N';` - res, err := db.Exec(sqlStatement, card_name, lnurlw_enable_yn, tx_limit_sats, day_limit_sats) + res, err := db.Exec(sqlStatement, card_name, lnurlw_enable_yn, tx_limit_sats, day_limit_sats, + pin_enable_yn, pin_number, pin_limit_sats) if err != nil { return err diff --git a/internalapi/createboltcard.go b/internalapi/createboltcard.go index ec4834a..ea9f913 100644 --- a/internalapi/createboltcard.go +++ b/internalapi/createboltcard.go @@ -83,12 +83,33 @@ func Createboltcard(w http.ResponseWriter, r *http.Request) { return } + pin_enable_flag_str := r.URL.Query().Get("enable_pin") + pin_enable_flag, err := strconv.ParseBool(pin_enable_flag_str) + if err != nil { + msg := "updateboltcard: enable_pin is not a valid boolean" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + + pin_number := r.URL.Query().Get("pin_number") + + pin_limit_sats_str := r.URL.Query().Get("pin_limit_sats") + pin_limit_sats, err := strconv.Atoi(pin_limit_sats_str) + if err != nil { + msg := "updateboltcard: pin_limit_sats is not a valid integer" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + // log the request log.WithFields(log.Fields{ "card_name": card_name, "tx_max": tx_max, "day_max": day_max, "enable": enable_flag, "uid_privacy": uid_privacy_flag, - "allow_neg_bal": allow_neg_bal_flag}).Info("createboltcard API request") + "allow_neg_bal": allow_neg_bal_flag, "enable_pin": pin_enable_flag, + "pin_number": pin_number, "pin_limit_sats": pin_limit_sats}).Info("createboltcard API request") // create the keys @@ -102,7 +123,7 @@ func Createboltcard(w http.ResponseWriter, r *http.Request) { err = db.Insert_card(one_time_code, k0_auth_key, k2_cmac_key, k3, k4, tx_max, day_max, enable_flag, card_name, - uid_privacy_flag, allow_neg_bal_flag) + uid_privacy_flag, allow_neg_bal_flag, pin_enable_flag, pin_number, pin_limit_sats) if err != nil { log.Warn(err.Error()) return diff --git a/internalapi/updateboltcard.go b/internalapi/updateboltcard.go index ae6ea20..ecc4f2b 100644 --- a/internalapi/updateboltcard.go +++ b/internalapi/updateboltcard.go @@ -43,6 +43,26 @@ func Updateboltcard(w http.ResponseWriter, r *http.Request) { return } + pin_enable_flag_str := r.URL.Query().Get("enable_pin") + pin_enable_flag, err := strconv.ParseBool(pin_enable_flag_str) + if err != nil { + msg := "updateboltcard: enable_pin is not a valid boolean" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + + pin_number := r.URL.Query().Get("pin_number") + + pin_limit_sats_str := r.URL.Query().Get("pin_limit_sats") + pin_limit_sats, err := strconv.Atoi(pin_limit_sats_str) + if err != nil { + msg := "updateboltcard: pin_limit_sats is not a valid integer" + log.Warn(msg) + resp_err.Write_message(w, msg) + return + } + card_name := r.URL.Query().Get("card_name") // check if card_name exists @@ -64,11 +84,12 @@ func Updateboltcard(w http.ResponseWriter, r *http.Request) { log.WithFields(log.Fields{ "card_name": card_name, "tx_max": tx_max, "day_max": day_max, - "enable": enable_flag}).Info("updateboltcard API request") + "enable": enable_flag, "enable_pin": pin_enable_flag, + "pin_number": pin_number, "pin_limit_sats": pin_limit_sats}).Info("updateboltcard API request") // update the card record - err = db.Update_card(card_name, enable_flag, tx_max, day_max) + err = db.Update_card(card_name, enable_flag, tx_max, day_max, pin_enable_flag, pin_number, pin_limit_sats) if err != nil { log.Warn(err.Error()) return diff --git a/script/s_create_db b/script/s_create_db index 1e0b7d8..aecb7b6 100755 --- a/script/s_create_db +++ b/script/s_create_db @@ -15,7 +15,7 @@ if [ "$x" = "y" ]; then psql postgres -f sql/create_db_init.sql psql postgres -f sql/create_db.sql psql postgres -f sql/create_db_user.sql - psql postgres -f sql/settings.sql + psql postgres -f sql/settings.sql.secret echo Database created else echo No action diff --git a/sql/create_db.sql b/sql/create_db.sql index 03c80f7..6021a33 100644 --- a/sql/create_db.sql +++ b/sql/create_db.sql @@ -28,6 +28,9 @@ CREATE TABLE cards ( one_time_code_expiry TIMESTAMPTZ DEFAULT NOW() + INTERVAL '1 DAY', one_time_code_used CHAR(1) NOT NULL DEFAULT 'Y', allow_negative_balance CHAR(1) NOT NULL DEFAULT 'N', + pin_enable CHAR(1) NOT NULL DEFAULT 'N', + pin_number CHAR(4) NOT NULL DEFAULT '0000', + pin_limit_sats INT NOT NULL, wiped CHAR(1) NOT NULL DEFAULT 'N', PRIMARY KEY(card_id) ); From 105323a6807f3e7c2f4df356868998cce0719487 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Sun, 2 Jul 2023 07:23:58 +0000 Subject: [PATCH 2/7] add testing --- lnurlw/lnurlw_request.go | 27 ++++++++++----------------- script/s_setup_test_data | 6 ++++++ sql/data.test.sql | 24 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 17 deletions(-) create mode 100755 script/s_setup_test_data create mode 100644 sql/data.test.sql diff --git a/lnurlw/lnurlw_request.go b/lnurlw/lnurlw_request.go index 50bc025..7fa5d6b 100644 --- a/lnurlw/lnurlw_request.go +++ b/lnurlw/lnurlw_request.go @@ -14,15 +14,6 @@ import ( "strings" ) -type ResponseData struct { - Tag string `json:"tag"` - Callback string `json:"callback"` - LnurlwK1 string `json:"k1"` - DefaultDescription string `json:"defaultDescription"` - MinWithdrawable int `json:"minWithdrawable"` - MaxWithdrawable int `json:"maxWithdrawable"` -} - func get_p_c(req *http.Request, p_name string, c_name string) (p string, c string) { params_p, ok := req.URL.Query()[p_name] @@ -255,6 +246,7 @@ func parse_request(req *http.Request) (int, error) { func Response(w http.ResponseWriter, req *http.Request) { env_host_domain := db.Get_setting("HOST_DOMAIN") + if req.Host != env_host_domain { log.Warn("wrong host domain") resp_err.Write(w) @@ -312,15 +304,16 @@ func Response(w http.ResponseWriter, req *http.Request) { return } - defalut_description := db.Get_setting("DEFAULT_DESCRIPTION") + default_description := db.Get_setting("DEFAULT_DESCRIPTION") - response := ResponseData{} - response.Tag = "withdrawRequest" - response.Callback = lnurlw_cb_url - response.LnurlwK1 = lnurlw_k1 - response.DefaultDescription = defalut_description - response.MinWithdrawable = min_withdraw_sats * 1000 // milliSats - response.MaxWithdrawable = max_withdraw_sats * 1000 // milliSats + response := make(map[string]interface{}) + + response["tag"] = "withdrawRequest" + response["callback"] = lnurlw_cb_url + response["k1"] = lnurlw_k1 + response["defaultDescription"] = default_description + response["minWithdrawable"] = min_withdraw_sats * 1000 // milliSats + response["maxWithdrawable"] = max_withdraw_sats * 1000 // milliSats jsonData, err := json.Marshal(response) diff --git a/script/s_setup_test_data b/script/s_setup_test_data new file mode 100755 index 0000000..7426df8 --- /dev/null +++ b/script/s_setup_test_data @@ -0,0 +1,6 @@ +# to close any database connections +sudo systemctl stop postgresql +sudo systemctl start postgresql + +psql postgres -f sql/data.test.sql +echo Test data added diff --git a/sql/data.test.sql b/sql/data.test.sql new file mode 100644 index 0000000..c5827dd --- /dev/null +++ b/sql/data.test.sql @@ -0,0 +1,24 @@ +-- connect to card_db +\c card_db; + +-- clear out table data +DELETE FROM settings; +DELETE FROM card_payments; +DELETE FROM card_receipts; +DELETE FROM cards; + +-- set up test data +INSERT INTO settings (name, value) VALUES ('LOG_LEVEL', 'DEBUG'); +INSERT INTO settings (name, value) VALUES ('AES_DECRYPT_KEY', '994de7f8156609a0effafbdb049337b1'); +INSERT INTO settings (name, value) VALUES ('HOST_DOMAIN', 'localhost:9000'); +INSERT INTO settings (name, value) VALUES ('FUNCTION_INTERNAL_API', 'ENABLE'); +INSERT INTO settings (name, value) VALUES ('MIN_WITHDRAW_SATS', '1'); +INSERT INTO settings (name, value) VALUES ('MAX_WITHDRAW_SATS', '1000'); + + +INSERT INTO cards + (k0_auth_key, k2_cmac_key, k3, k4, lnurlw_enable, last_counter_value, lnurlw_request_timeout_sec, + tx_limit_sats, day_limit_sats, card_name, pin_limit_sats) + VALUES + ('', 'd3dffa1e12d2477e443a6ee9fcfeab18', '', '', 'Y', 0, 10, + 0, 0, 'test_card', 0); From 3d9e742dc1137ac12a8fe08b90898b91cb87ae62 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Sun, 2 Jul 2023 13:11:38 +0000 Subject: [PATCH 3/7] pinLimit added to lnurlw response --- db/db.go | 11 +++++++++-- lnurlw/lnurlw_request.go | 13 +++++++++++++ sql/data.test.sql | 4 ++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/db/db.go b/db/db.go index 41a7d29..8b1b406 100644 --- a/db/db.go +++ b/db/db.go @@ -29,6 +29,9 @@ type Card struct { One_time_code string Card_name string Allow_negative_balance string + Pin_enable string + Pin_number string + Pin_limit_sats int } type Payment struct { @@ -350,7 +353,8 @@ func Get_card_from_card_id(card_id int) (*Card, error) { `last_counter_value, lnurlw_request_timeout_sec, ` + `lnurlw_enable, tx_limit_sats, day_limit_sats, ` + `email_enable, email_address, card_name, ` + - `allow_negative_balance FROM cards WHERE card_id=$1;` + `allow_negative_balance, pin_enable, pin_number, ` + + `pin_limit_sats FROM cards WHERE card_id=$1;` row := db.QueryRow(sqlStatement, card_id) err = row.Scan( &c.Card_id, @@ -364,7 +368,10 @@ func Get_card_from_card_id(card_id int) (*Card, error) { &c.Email_enable, &c.Email_address, &c.Card_name, - &c.Allow_negative_balance) + &c.Allow_negative_balance, + &c.Pin_enable, + &c.Pin_number, + &c.Pin_limit_sats) if err != nil { return &c, err } diff --git a/lnurlw/lnurlw_request.go b/lnurlw/lnurlw_request.go index 7fa5d6b..eb0b15f 100644 --- a/lnurlw/lnurlw_request.go +++ b/lnurlw/lnurlw_request.go @@ -304,6 +304,15 @@ func Response(w http.ResponseWriter, req *http.Request) { return } + // get pin_enable & pin_limit_sats + + c, err := db.Get_card_from_card_id(card_id) + if err != nil { + log.WithFields(log.Fields{"card_id": card_id}).Warn(err) + resp_err.Write(w) + return + } + default_description := db.Get_setting("DEFAULT_DESCRIPTION") response := make(map[string]interface{}) @@ -315,6 +324,10 @@ func Response(w http.ResponseWriter, req *http.Request) { response["minWithdrawable"] = min_withdraw_sats * 1000 // milliSats response["maxWithdrawable"] = max_withdraw_sats * 1000 // milliSats + if c.Pin_enable == "Y" { + response["pinLimit"] = c.Pin_limit_sats * 1000 // milliSats + } + jsonData, err := json.Marshal(response) if err != nil { diff --git a/sql/data.test.sql b/sql/data.test.sql index c5827dd..cae568a 100644 --- a/sql/data.test.sql +++ b/sql/data.test.sql @@ -18,7 +18,7 @@ INSERT INTO settings (name, value) VALUES ('MAX_WITHDRAW_SATS', '1000'); INSERT INTO cards (k0_auth_key, k2_cmac_key, k3, k4, lnurlw_enable, last_counter_value, lnurlw_request_timeout_sec, - tx_limit_sats, day_limit_sats, card_name, pin_limit_sats) + tx_limit_sats, day_limit_sats, card_name, pin_enable, pin_number, pin_limit_sats) VALUES ('', 'd3dffa1e12d2477e443a6ee9fcfeab18', '', '', 'Y', 0, 10, - 0, 0, 'test_card', 0); + 0, 0, 'test_card', 'Y', '1234', 1000); From 6609558f96261dd1b8675ac9c08477fd318c172c Mon Sep 17 00:00:00 2001 From: Chloe Jung Date: Mon, 17 Jul 2023 11:59:07 +1200 Subject: [PATCH 4/7] When returning boltcard data through api, send pin_enable and pin_limit_sats values as well --- db/db.go | 6 ++++-- internalapi/getboltcard.go | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/db/db.go b/db/db.go index 8b1b406..3ff623a 100644 --- a/db/db.go +++ b/db/db.go @@ -392,7 +392,7 @@ func Get_card_from_card_name(card_name string) (*Card, error) { sqlStatement := `SELECT card_id, k2_cmac_key, uid,` + ` last_counter_value, lnurlw_request_timeout_sec,` + - ` lnurlw_enable, tx_limit_sats, day_limit_sats` + + ` lnurlw_enable, tx_limit_sats, day_limit_sats, pin_enable, pin_limit_sats` + ` FROM cards WHERE card_name=$1 AND wiped = 'N';` row := db.QueryRow(sqlStatement, card_name) err = row.Scan( @@ -403,7 +403,9 @@ func Get_card_from_card_name(card_name string) (*Card, error) { &c.Lnurlw_request_timeout_sec, &c.Lnurlw_enable, &c.Tx_limit_sats, - &c.Day_limit_sats) + &c.Day_limit_sats, + &c.Pin_enable, + &c.Pin_limit_sats) if err != nil { return &c, err } diff --git a/internalapi/getboltcard.go b/internalapi/getboltcard.go index aef2847..9f3f390 100644 --- a/internalapi/getboltcard.go +++ b/internalapi/getboltcard.go @@ -37,7 +37,9 @@ func Getboltcard(w http.ResponseWriter, r *http.Request) { `"uid": "` + c.Db_uid + `",` + `"lnurlw_enable": "` + c.Lnurlw_enable + `",` + `"tx_limit_sats": "` + strconv.Itoa(c.Tx_limit_sats) + `",` + - `"day_limit_sats": "` + strconv.Itoa(c.Day_limit_sats) + `"}`) + `"day_limit_sats": "` + strconv.Itoa(c.Day_limit_sats) + `", ` + + `"pin_enable": "` + strconv.Itoa(c.Pin_enable) + `", ` + + `"pin_limit_sats": "` + strconv.Itoa(c.Pin_limit_sats) + `"}`) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) From 598919fc2a0a8248ec8edd42c392b65e964526c1 Mon Sep 17 00:00:00 2001 From: Chloe Jung Date: Mon, 17 Jul 2023 12:16:55 +1200 Subject: [PATCH 5/7] Fix parse error --- internalapi/getboltcard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internalapi/getboltcard.go b/internalapi/getboltcard.go index 9f3f390..0c1b605 100644 --- a/internalapi/getboltcard.go +++ b/internalapi/getboltcard.go @@ -38,7 +38,7 @@ func Getboltcard(w http.ResponseWriter, r *http.Request) { `"lnurlw_enable": "` + c.Lnurlw_enable + `",` + `"tx_limit_sats": "` + strconv.Itoa(c.Tx_limit_sats) + `",` + `"day_limit_sats": "` + strconv.Itoa(c.Day_limit_sats) + `", ` + - `"pin_enable": "` + strconv.Itoa(c.Pin_enable) + `", ` + + `"pin_enable": "` + c.Pin_enable + `", ` + `"pin_limit_sats": "` + strconv.Itoa(c.Pin_limit_sats) + `"}`) w.Header().Set("Content-Type", "application/json") From 87306ca6db9a8445471348e0b9fbaa93e3e068b1 Mon Sep 17 00:00:00 2001 From: Chloe Jung Date: Mon, 17 Jul 2023 13:59:37 +1200 Subject: [PATCH 6/7] Format --- internalapi/getboltcard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internalapi/getboltcard.go b/internalapi/getboltcard.go index 0c1b605..0103752 100644 --- a/internalapi/getboltcard.go +++ b/internalapi/getboltcard.go @@ -37,8 +37,8 @@ func Getboltcard(w http.ResponseWriter, r *http.Request) { `"uid": "` + c.Db_uid + `",` + `"lnurlw_enable": "` + c.Lnurlw_enable + `",` + `"tx_limit_sats": "` + strconv.Itoa(c.Tx_limit_sats) + `",` + - `"day_limit_sats": "` + strconv.Itoa(c.Day_limit_sats) + `", ` + - `"pin_enable": "` + c.Pin_enable + `", ` + + `"day_limit_sats": "` + strconv.Itoa(c.Day_limit_sats) + `", ` + + `"pin_enable": "` + c.Pin_enable + `", ` + `"pin_limit_sats": "` + strconv.Itoa(c.Pin_limit_sats) + `"}`) w.Header().Set("Content-Type", "application/json") From 6c03c1c3d93ece33e81d56532f4c651723bbf9d8 Mon Sep 17 00:00:00 2001 From: Peter Rounce Date: Thu, 20 Jul 2023 11:00:37 +0000 Subject: [PATCH 7/7] check pin in payment rules --- lnurlw/lnurlw_callback.go | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/lnurlw/lnurlw_callback.go b/lnurlw/lnurlw_callback.go index b5d5a61..f07e1b0 100644 --- a/lnurlw/lnurlw_callback.go +++ b/lnurlw/lnurlw_callback.go @@ -225,17 +225,15 @@ func Callback(w http.ResponseWriter, req *http.Request) { url := req.URL.RequestURI() log.WithFields(log.Fields{"url": url}).Debug("cb request") - // check k1 value - params_k1, ok := req.URL.Query()["k1"] + // get k1 value + param_k1 := req.URL.Query().Get("k1") - if !ok || len(params_k1[0]) < 1 { + if param_k1 == "" { log.WithFields(log.Fields{"url": url}).Debug("k1 not found") resp_err.Write(w) return } - param_k1 := params_k1[0] - p, err := db.Get_payment_k1(param_k1) if err != nil { log.WithFields(log.Fields{"url": url, "k1": param_k1}).Warn(err) @@ -263,14 +261,14 @@ func Callback(w http.ResponseWriter, req *http.Request) { return } - params_pr, ok := req.URL.Query()["pr"] - if !ok || len(params_pr[0]) < 1 { + // get the payment request + param_pr := req.URL.Query().Get("pr") + if param_pr == "" { log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn("pr field not found") resp_err.Write(w) return } - param_pr := params_pr[0] bolt11, _ := decodepay.Decodepay(param_pr) // record the lightning invoice @@ -283,6 +281,23 @@ func Callback(w http.ResponseWriter, req *http.Request) { log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Debug("checking payment rules") + // get the pin if it has been passed in + param_pin := req.URL.Query().Get("pin") + + c, err := db.Get_card_from_card_id(p.Card_id) + if err != nil { + log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn(err) + resp_err.Write(w) + return + } + + // check the pin if needed + if c.Pin_enable == "Y" && int(bolt11.MSatoshi/1000) >= c.Pin_limit_sats && c.Pin_number != param_pin { + log.WithFields(log.Fields{"card_payment_id": p.Card_payment_id}).Warn("incorrect pin provided") + resp_err.Write(w) + return + } + // check if we are only sending funds to a defined test node testnode := db.Get_setting("LN_TESTNODE") if testnode != "" && bolt11.Payee != testnode {