github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/litrpc/addrlib.go (about)

     1  package litrpc
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/mit-dci/lit/logging"
     7  
     8  	"github.com/mit-dci/lit/bech32"
     9  	"github.com/mit-dci/lit/btcutil/base58"
    10  	"github.com/mit-dci/lit/coinparam"
    11  	"github.com/mit-dci/lit/lnutil"
    12  )
    13  
    14  /*
    15  Multi-wallet address functions that maybe should be in another package
    16  (btcutil? chaincfg?) but are here for now since modifying btcd is hard.
    17  
    18  */
    19  
    20  // AdrStringToOutscript converts an address string into an output script byte slice
    21  // note that this ignores the prefix! Be careful not to mix networks.
    22  // currently only works for testnet legacy addresses
    23  func AdrStringToOutscript(adr string) ([]byte, error) {
    24  	var err error
    25  	var outScript []byte
    26  
    27  	// use HRP to determine network / wallet to use
    28  	outScript, err = bech32.SegWitAddressDecode(adr)
    29  	if err != nil { // valid bech32 string
    30  		// try for base58 address
    31  		// btcutil addresses don't really work as they won't tell you the
    32  		// network; you have to tell THEM the network, which defeats the point
    33  		// of having an address.  default to testnet only here
    34  
    35  		// could work on adding more old-style addresses; for now use new bech32
    36  		// addresses for multi-wallet / segwit sends.
    37  
    38  		// ignore netID here
    39  		decoded, _, err := base58.CheckDecode(adr)
    40  		if err != nil {
    41  			return nil, err
    42  		}
    43  
    44  		outScript, err = lnutil.PayToPubKeyHashScript(decoded)
    45  		if err != nil {
    46  			return nil, err
    47  		}
    48  	}
    49  	return outScript, nil
    50  }
    51  
    52  // Default to testnet for unknown / bad addrs.
    53  func CoinTypeFromAdr(adr string) uint32 {
    54  	ct, err := CoinTypeFromBechAdr(adr)
    55  	if err == nil {
    56  		return ct
    57  	}
    58  	logging.Errorf("cointype from bech32 error: %s\n", err.Error())
    59  
    60  	if len(adr) < 5 {
    61  		// well that's not even an address
    62  		return 12345
    63  	}
    64  	if strings.HasPrefix(adr, "m") || strings.HasPrefix(adr, "n") {
    65  		// guess testnet; could be regtest
    66  		return 1
    67  	}
    68  	if strings.HasPrefix(adr, "V") {
    69  		return 28
    70  	}
    71  	if strings.HasPrefix(adr, "X") || strings.HasPrefix(adr, "W") {
    72  		return 65536
    73  	}
    74  	// add other prefixes here...
    75  	return 1
    76  }
    77  
    78  // Gives the cointype from an address string (if known)
    79  func CoinTypeFromBechAdr(adr string) (uint32, error) {
    80  	hrp, err := bech32.GetHRP(adr)
    81  	if err != nil {
    82  		return 0, err
    83  	}
    84  	return coinparam.PrefixToCoinType(hrp)
    85  }