cashless2ecash

cashless2ecash: pay with cards for digital cash (experimental)
Log | Files | Refs | README

payto.go (3011B)


      1 // This file is part of taler-cashless2ecash.
      2 // Copyright (C) 2024 Joel Häberli
      3 //
      4 // taler-cashless2ecash is free software: you can redistribute it and/or modify it
      5 // under the terms of the GNU Affero General Public License as published
      6 // by the Free Software Foundation, either version 3 of the License,
      7 // or (at your option) any later version.
      8 //
      9 // taler-cashless2ecash is distributed in the hope that it will be useful, but
     10 // WITHOUT ANY WARRANTY; without even the implied warranty of
     11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 // Affero General Public License for more details.
     13 //
     14 // You should have received a copy of the GNU Affero General Public License
     15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 //
     17 // SPDX-License-Identifier: AGPL3.0-or-later
     18 
     19 package internal_utils
     20 
     21 import (
     22 	"errors"
     23 	"fmt"
     24 	"strings"
     25 )
     26 
     27 const PAYTO_PARTS_SEPARATOR = "/"
     28 
     29 const PAYTO_SCHEME_PREFIX = "payto://"
     30 const PAYTO_TAGRET_TYPE_IBAN = "iban"
     31 const PAYTO_TARGET_TYPE_WALLEE_TRANSACTION = "wallee-transaction"
     32 
     33 var REGISTERED_TARGET_TYPES = []string{
     34 	"ach",
     35 	"bic",
     36 	"iban",
     37 	"upi",
     38 	"bitcoin",
     39 	"ilp",
     40 	"void",
     41 	"ldap",
     42 	"eth",
     43 	"interac-etransfer",
     44 	"wallee-transaction",
     45 }
     46 
     47 // This function parses a payto-uri (RFC 8905: https://www.rfc-editor.org/rfc/rfc8905.html)
     48 // The function only parses the target type "wallee-transaction" as specified
     49 // in the payto GANA registry (https://gana.gnunet.org/payto-payment-target-types/payto_payment_target_types.html)
     50 func ParsePaytoWalleeTransaction(uri string) (string, string, error) {
     51 
     52 	if t, i, err := ParsePaytoUri(uri); err != nil {
     53 
     54 		if t != "wallee-transaction" {
     55 			return "", "", errors.New("expected payto target type 'wallee-transaction'")
     56 		}
     57 
     58 		return t, i, nil
     59 	} else {
     60 		return t, "", err
     61 	}
     62 }
     63 
     64 // returns the Payto Target Type and Target Identifier as string
     65 // if the uri is malformed, an error is returned (target type and
     66 // identifier will be empty strings).
     67 func ParsePaytoUri(uri string) (string, string, error) {
     68 
     69 	if raw, found := strings.CutPrefix(uri, PAYTO_SCHEME_PREFIX); found {
     70 
     71 		parts := strings.Split(raw, PAYTO_PARTS_SEPARATOR)
     72 		if len(parts) < 2 {
     73 			return "", "", errors.New("invalid payto-uri")
     74 		}
     75 
     76 		return parts[0], parts[1], nil
     77 	}
     78 	return "", "", errors.New("invalid payto-uri")
     79 }
     80 
     81 func FormatPaytoWalleeTransaction(tid int) string {
     82 	return fmt.Sprintf("%s%s/%d",
     83 		PAYTO_SCHEME_PREFIX,
     84 		PAYTO_TARGET_TYPE_WALLEE_TRANSACTION,
     85 		tid,
     86 	)
     87 }
     88 
     89 func ParsePaytoTargetType(uri string) (string, error) {
     90 
     91 	if raw, found := strings.CutPrefix(uri, PAYTO_SCHEME_PREFIX); found {
     92 
     93 		parts := strings.Split(raw, PAYTO_PARTS_SEPARATOR)
     94 		if len(parts) < 2 {
     95 			return "", errors.New("invalid wallee-transaction payto-uri")
     96 		}
     97 
     98 		for _, target := range REGISTERED_TARGET_TYPES {
     99 			if strings.EqualFold(target, parts[0]) {
    100 				return parts[0], nil
    101 			}
    102 		}
    103 		return "", errors.New("target type '" + parts[0] + "' is not registered")
    104 	}
    105 	return "", errors.New("invalid payto-uri")
    106 }