diff --git a/create_db.sql b/create_db.sql index efa9a83..d2192c9 100644 --- a/create_db.sql +++ b/create_db.sql @@ -22,6 +22,7 @@ CREATE TABLE cards ( card_name VARCHAR(100) UNIQUE NOT NULL DEFAULT '', email_address VARCHAR(100) DEFAULT '', email_enable CHAR(1) NOT NULL DEFAULT 'N', + uid_privacy CHAR(1) NOT NULL DEFAULT 'N', one_time_code CHAR(32) NOT NULL DEFAULT '', one_time_code_expiry TIMESTAMPTZ DEFAULT NOW() + INTERVAL '1 DAY', one_time_code_used CHAR(1) NOT NULL DEFAULT 'Y', diff --git a/createboltcard/database.go b/createboltcard/database.go index 71c8739..0c26e3f 100644 --- a/createboltcard/database.go +++ b/createboltcard/database.go @@ -49,13 +49,17 @@ func db_get_card_name_count(card_name string) (card_count int, err error) { } func db_insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string, k3 string, k4 string, - tx_max_sats int, day_max_sats int, lnurlw_enable bool, card_name string) error { + tx_max_sats int, day_max_sats int, lnurlw_enable bool, card_name string, uid_privacy bool, + allow_neg_bal_ptr bool) error { lnurlw_enable_yn := "N" + if lnurlw_enable { lnurlw_enable_yn = "Y" } - if lnurlw_enable == true { - lnurlw_enable_yn = "Y" - } + uid_privacy_yn := "N" + if uid_privacy { uid_privacy_yn = "Y" } + + allow_neg_bal_yn := "N" + if allow_neg_bal_ptr { allow_neg_bal_yn = "Y" } db, err := db_open() if err != nil { @@ -68,10 +72,11 @@ func db_insert_card(one_time_code string, k0_auth_key string, k2_cmac_key string 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)` + - ` VALUES ($1, $2, $3, $4, $5, '', 0, 60, $6, $7, $8, 'N', $9);` + ` 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);` res, err := db.Exec(sqlStatement, one_time_code, k0_auth_key, k2_cmac_key, k3, k4, - tx_max_sats, day_max_sats, lnurlw_enable_yn, card_name) + tx_max_sats, day_max_sats, lnurlw_enable_yn, card_name, uid_privacy_yn, + allow_neg_bal_yn) if err != nil { return err } diff --git a/createboltcard/main.go b/createboltcard/main.go index e08d2f8..84f66ec 100644 --- a/createboltcard/main.go +++ b/createboltcard/main.go @@ -28,6 +28,8 @@ func main() { day_max_ptr := flag.Int("day_max", 0, "set the maximum satoshis per 24 hour day") enable_flag_ptr := flag.Bool("enable", false, "enable the card for payments") card_name_ptr := flag.String("name", "", "set a name for the card (must be set)") + uid_privacy_ptr := flag.Bool("uid_privacy", false, "select enhanced privacy for the card (cannot undo)") + allow_neg_bal_ptr := flag.Bool("allow_neg_bal", false, "allow the card to have a negative balance") flag.Parse() @@ -60,7 +62,8 @@ func main() { // create the new card record err = db_insert_card(one_time_code, k0_auth_key, k2_cmac_key, k3, k4, - *tx_max_ptr, *day_max_ptr, *enable_flag_ptr, *card_name_ptr) + *tx_max_ptr, *day_max_ptr, *enable_flag_ptr, *card_name_ptr, + *uid_privacy_ptr, *allow_neg_bal_ptr) if err != nil { log.Warn(err.Error()) return diff --git a/database.go b/database.go index d224c1b..fba04cf 100644 --- a/database.go +++ b/database.go @@ -25,6 +25,7 @@ type card struct { lnurlp_enable string email_address string email_enable string + uid_privacy string one_time_code string card_name string allow_negative_balance string @@ -74,7 +75,7 @@ func db_get_new_card(one_time_code string) (*card, error) { } defer db.Close() - sqlStatement := `SELECT k0_auth_key, k2_cmac_key, k3, k4, card_name` + + sqlStatement := `SELECT k0_auth_key, k2_cmac_key, k3, k4, card_name, uid_privacy` + ` FROM cards WHERE one_time_code=$1 AND` + ` one_time_code_expiry > NOW() AND one_time_code_used = 'N' AND wiped = 'N';` row := db.QueryRow(sqlStatement, one_time_code) @@ -83,7 +84,8 @@ func db_get_new_card(one_time_code string) (*card, error) { &c.k2_cmac_key, &c.k3, &c.k4, - &c.card_name) + &c.card_name, + &c.uid_privacy) if err != nil { return &c, err } diff --git a/new_card_request.go b/new_card_request.go index 8f1a4e4..a5f977d 100644 --- a/new_card_request.go +++ b/new_card_request.go @@ -24,6 +24,7 @@ import ( * @apiSuccess {String} k2 Key 2 - authentication key * @apiSuccess {String} k3 Key 3 - NXP documents say this must be set * @apiSuccess {String} k4 Key 4 - NXP documents say this must be set + * @apiSuccess {String} uid_privacy - set up the card for the UID to be private */ type NewCardResponse struct { @@ -36,6 +37,7 @@ type NewCardResponse struct { K2 string `json:"k2"` K3 string `json:"k3"` K4 string `json:"k4"` + UID_PRIVACY string `json:"uid_privacy"` } func new_card_request(w http.ResponseWriter, req *http.Request) { @@ -72,7 +74,7 @@ func new_card_request(w http.ResponseWriter, req *http.Request) { response := NewCardResponse{} response.PROTOCOL_NAME = "create_bolt_card_response" - response.PROTOCOL_VERSION = 1 + response.PROTOCOL_VERSION = 2 response.CARD_NAME = c.card_name response.LNURLW_BASE = lnurlw_base response.K0 = c.k0_auth_key @@ -80,6 +82,7 @@ func new_card_request(w http.ResponseWriter, req *http.Request) { response.K2 = c.k2_cmac_key response.K3 = c.k3 response.K4 = c.k4 + response.UID_PRIVACY = c.uid_privacy log.SetFormatter(&log.JSONFormatter{ DisableHTMLEscape: true,