use database settings for lookups
This commit is contained in:
parent
085b402fef
commit
59151232dd
13 changed files with 87 additions and 42 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -16,9 +16,9 @@ createboltcard/createboltcard
|
||||||
# Dependency directories (remove the comment below to include it)
|
# Dependency directories (remove the comment below to include it)
|
||||||
# vendor/
|
# vendor/
|
||||||
|
|
||||||
# secrets
|
# possible secrets
|
||||||
tls.cert
|
tls.cert
|
||||||
*.macaroon*
|
*.macaroon*
|
||||||
add_test_data.sql
|
|
||||||
Caddyfile
|
Caddyfile
|
||||||
boltcard.service
|
boltcard.service
|
||||||
|
*.secret
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ func main() {
|
||||||
|
|
||||||
// show a QR code on the console for the URI + one_time_code
|
// show a QR code on the console for the URI + one_time_code
|
||||||
|
|
||||||
hostdomain := os.Getenv("HOST_DOMAIN")
|
hostdomain := db_get_setting("HOST_DOMAIN")
|
||||||
url := ""
|
url := ""
|
||||||
if strings.HasSuffix(hostdomain, ".onion") {
|
if strings.HasSuffix(hostdomain, ".onion") {
|
||||||
url = "http://" + hostdomain + "/new?a=" + one_time_code
|
url = "http://" + hostdomain + "/new?a=" + one_time_code
|
||||||
|
|
|
||||||
21
database.go
21
database.go
|
|
@ -65,6 +65,27 @@ func db_open() (*sql.DB, error) {
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func db_get_setting(setting_name string) (string) {
|
||||||
|
|
||||||
|
setting_value := ""
|
||||||
|
|
||||||
|
db, err := db_open()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
sqlStatement := `select value from settings where name=$1;`
|
||||||
|
|
||||||
|
row := db.QueryRow(sqlStatement, setting_name)
|
||||||
|
err = row.Scan(&setting_value)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return setting_value
|
||||||
|
}
|
||||||
|
|
||||||
func db_get_new_card(one_time_code string) (*card, error) {
|
func db_get_new_card(one_time_code string) (*card, error) {
|
||||||
|
|
||||||
c := card{}
|
c := card{}
|
||||||
|
|
|
||||||
20
docs/SETTINGS.md
Normal file
20
docs/SETTINGS.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Settings
|
||||||
|
|
||||||
|
The database connection settings are in the system environment variables.
|
||||||
|
All other settings are in the database in a `settings` table.
|
||||||
|
|
||||||
|
- LOG_LEVEL
|
||||||
|
- AES_DECRYPT_KEY
|
||||||
|
- HOST_DOMAIN
|
||||||
|
- MIN_WITHDRAW_SATS
|
||||||
|
- MAX_WITHDRAW_SATS
|
||||||
|
- LN_HOST
|
||||||
|
- LN_PORT
|
||||||
|
- LN_TLS_FILE
|
||||||
|
- LN_MACAROON_FILE
|
||||||
|
- FEE_LIMIT_SAT
|
||||||
|
- FEE_LIMIT_PERCENT
|
||||||
|
- LN_TESTNODE
|
||||||
|
- FUNCTION_LNURLW
|
||||||
|
- FUNCTION_LNURLP
|
||||||
|
- FUNCTION_EMAIL
|
||||||
8
email.go
8
email.go
|
|
@ -26,7 +26,7 @@ func send_balance_email(recipient_email string, card_id int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
email_max_txs, err := strconv.Atoi(os.Getenv("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
|
||||||
|
|
@ -89,9 +89,9 @@ func send_balance_email(recipient_email string, card_id int) {
|
||||||
|
|
||||||
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 := os.Getenv("AWS_SES_ID")
|
aws_ses_id := db_get_setting("AWS_SES_ID")
|
||||||
aws_ses_secret := os.Getenv("AWS_SES_SECRET")
|
aws_ses_secret := db_get_setting("AWS_SES_SECRET")
|
||||||
sender := os.Getenv("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"),
|
||||||
|
|
|
||||||
28
lightning.go
28
lightning.go
|
|
@ -75,7 +75,7 @@ func getGrpcConn(hostname string, port int, tlsFile, macaroonFile string) *grpc.
|
||||||
|
|
||||||
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(os.Getenv("LN_PORT"))
|
ln_port, err := strconv.Atoi(db_get_setting("LN_PORT"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -83,10 +83,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(
|
||||||
os.Getenv("LN_HOST"),
|
db_get_setting("LN_HOST"),
|
||||||
ln_port,
|
ln_port,
|
||||||
os.Getenv("LN_TLS_FILE"),
|
db_get_setting("LN_TLS_FILE"),
|
||||||
os.Getenv("LN_MACAROON_FILE"))
|
db_get_setting("LN_MACAROON_FILE"))
|
||||||
|
|
||||||
l_client := lnrpc.NewLightningClient(connection)
|
l_client := lnrpc.NewLightningClient(connection)
|
||||||
|
|
||||||
|
|
@ -113,17 +113,17 @@ func monitor_invoice_state(r_hash []byte) () {
|
||||||
|
|
||||||
// get node parameters from environment variables
|
// get node parameters from environment variables
|
||||||
|
|
||||||
ln_port, err := strconv.Atoi(os.Getenv("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(
|
||||||
os.Getenv("LN_HOST"),
|
db_get_setting("LN_HOST"),
|
||||||
ln_port,
|
ln_port,
|
||||||
os.Getenv("LN_TLS_FILE"),
|
db_get_setting("LN_TLS_FILE"),
|
||||||
os.Getenv("LN_MACAROON_FILE"))
|
db_get_setting("LN_MACAROON_FILE"))
|
||||||
|
|
||||||
i_client := invoicesrpc.NewInvoicesClient(connection)
|
i_client := invoicesrpc.NewInvoicesClient(connection)
|
||||||
|
|
||||||
|
|
@ -196,28 +196,28 @@ func pay_invoice(card_payment_id int, invoice string) {
|
||||||
|
|
||||||
// get node parameters from environment variables
|
// get node parameters from environment variables
|
||||||
|
|
||||||
ln_port, err := strconv.Atoi(os.Getenv("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(
|
||||||
os.Getenv("LN_HOST"),
|
db_get_setting("LN_HOST"),
|
||||||
ln_port,
|
ln_port,
|
||||||
os.Getenv("LN_TLS_FILE"),
|
db_get_setting("LN_TLS_FILE"),
|
||||||
os.Getenv("LN_MACAROON_FILE"))
|
db_get_setting("LN_MACAROON_FILE"))
|
||||||
|
|
||||||
r_client := routerrpc.NewRouterClient(connection)
|
r_client := routerrpc.NewRouterClient(connection)
|
||||||
|
|
||||||
fee_limit_sat_str := os.Getenv("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 := os.Getenv("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)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
func lnurlp_callback(w http.ResponseWriter, r *http.Request) {
|
||||||
if os.Getenv("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
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +34,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 := os.Getenv("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)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
||||||
if os.Getenv("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
|
||||||
}
|
}
|
||||||
|
|
@ -22,9 +22,9 @@ func lnurlp_response(w http.ResponseWriter, r *http.Request) {
|
||||||
"r.Host": r.Host,
|
"r.Host": r.Host,
|
||||||
},).Info("lnurlp_response")
|
},).Info("lnurlp_response")
|
||||||
|
|
||||||
// look up domain in env vars (HOST_DOMAIN)
|
// look up domain setting (HOST_DOMAIN)
|
||||||
|
|
||||||
domain := os.Getenv("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)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
env_host_domain := os.Getenv("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)
|
||||||
|
|
@ -78,7 +78,7 @@ func lnurlw_callback(w http.ResponseWriter, req *http.Request) {
|
||||||
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 := os.Getenv("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)
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
// decrypt p with aes_decrypt_key
|
// decrypt p with aes_decrypt_key
|
||||||
|
|
||||||
aes_decrypt_key := os.Getenv("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)
|
||||||
|
|
||||||
|
|
@ -246,7 +246,7 @@ func parse_request(req *http.Request) (int, error) {
|
||||||
|
|
||||||
func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
env_host_domain := os.Getenv("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)
|
||||||
|
|
@ -286,7 +286,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 := os.Getenv("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 +295,7 @@ func lnurlw_response(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
max_withdraw_sats_str := os.Getenv("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 {
|
||||||
|
|
|
||||||
20
main.go
20
main.go
|
|
@ -25,13 +25,17 @@ func write_error_message(w http.ResponseWriter, message string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log_level := os.Getenv("LOG_LEVEL")
|
log_level := db_get_setting("LOG_LEVEL")
|
||||||
|
|
||||||
if log_level == "DEBUG" {
|
switch log_level {
|
||||||
log.SetLevel(log.DebugLevel)
|
case "DEBUG":
|
||||||
log.Info("bolt card service started - debug log level")
|
log.SetLevel(log.DebugLevel)
|
||||||
} else {
|
log.Info("bolt card service started - debug log level")
|
||||||
log.Info("bolt card service started - production log level")
|
case "PRODUCTION":
|
||||||
|
log.Info("bolt card service started - production log level")
|
||||||
|
default:
|
||||||
|
// log.Fatal calls os.Exit(1) after logging the error
|
||||||
|
log.Fatal("error getting a valid LOG_LEVEL setting from the database")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.SetFormatter(&log.JSONFormatter{
|
log.SetFormatter(&log.JSONFormatter{
|
||||||
|
|
@ -47,8 +51,8 @@ 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 := os.Getenv("HOST_PORT")
|
port := db_get_setting("HOST_PORT")
|
||||||
if len(port) == 0 {
|
if port == "" {
|
||||||
port = "9000"
|
port = "9000"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func new_card_request(w http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
k1_decrypt_key := os.Getenv("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"
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ func db_wipe_card(card_name string) (*card_wipe_info, error) {
|
||||||
return &card_wipe_info, err
|
return &card_wipe_info, err
|
||||||
}
|
}
|
||||||
|
|
||||||
card_wipe_info.k1 = os.Getenv("AES_DECRYPT_KEY")
|
card_wipe_info.k1 = db_get_setting("AES_DECRYPT_KEY")
|
||||||
|
|
||||||
return &card_wipe_info, nil
|
return &card_wipe_info, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue