func getKeyList() []string {
	var keys []string
	err := db.View(func(txn *badger.Txn) error {
		opts := badger.DefaultIteratorOptions
		opts.PrefetchValues = false
		it := txn.NewIterator(opts)
		defer it.Close()
		for it.Rewind(); it.Valid(); it.Next() {
			item := it.Item()
			keys = append(keys, string(item.Key()))
		}
		return nil
	})
	if err != nil {
		fmt.Println(Colour("Red", err.Error()))
		return []string{}
	}
	return keys
}
getKeyList retrieves a list of keys to pass to other functions.
package main
import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base32"
	"encoding/binary"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/user"
	"regexp"
	"strconv"
	"strings"
	"time"
	badger "github.com/dgraph-io/badger/v2"
	"github.com/manifoldco/promptui"
)
var db *badger.DB
type Items struct {
	Items []Item `json:"items"`
}
type Item struct {
	Type         string `json:"type"`
	Title        string `json:"title"`
	Arg          string `json:"arg"`
	Autocomplete string `json:"autocomplete"`
}
func Colour(colour, text string) string {
	colours := map[string]string{
		"Red":     "\033[1;31m%s\033[0m",
		"Green":   "\033[01;32m%s\033[0m",
		"Blue":    "\033[1;34m%s\033[0m",
		"Magenta": "\033[1;35m%s\033[0m",
	}
	return fmt.Sprintf(colours[colour], text)
}
func (i *Items) addTo(title, key string) []Item {
	i.Items = append(i.Items, Item{
		Type:         "default",
		Title:        title,
		Arg:          key,
		Autocomplete: key,
	})
	return i.Items
}
func main() {
	const version = "0.7.1"
	var err error
	flag.Parse()
	args := flag.Args()
	db, err = initDb()
	if err != nil {
		fmt.Println(Colour("Red", err.Error()))
		return
	}
	defer db.Close()
	if len(args) == 0 {
		prompt()
		return
	}
	if args[0] == "v" || args[0] == "version" {
		fmt.Printf("%s %s\n", Colour("Green", "Version"), Colour("Blue", version))
		return
	}
	if args[0] == "help" {
		fmt.Printf("%s\n", Colour("Green", "WELCOME TO GOTP"))
		fmt.Printf("%s\n\n", "The purpose of this package is to help with getting a 2FA otp without having to go through the shlep of taking your phone out and typing in the otp (though it's probably meant to be tedious... security via tediousnessness).")
		fmt.Printf("%s\n%s\n%s\n%s\n%s\n\n", Colour("Green", "ADD A NEW TOKEN"), Colour("Magenta", "gotp add key token."), "eg:", Colour("Blue", "gotp add key 564HJKHJKHKKKHGJKHJKYUFHFGHJ65E"), Colour("Blue", "gotp add key - local 564HJKHJKHKKKHGJKHJKYUFHFGHJ65E"))
		fmt.Printf("%s\n%s\n%s\n%s\n%s\n\n", Colour("Green", "LIST KEYS"), Colour("Blue", "gotp ls"), "And example of the output would be:", Colour("Magenta", "1: key"), Colour("Magenta", "2: key - local"))
		fmt.Printf("%s\n%s\n%s\n%s\n%s\n%s\n\n", Colour("Green", "GET OTP"), Colour("Magenta", "gotp key"), Colour("Magenta", "gotp get key"), "or you could use the index from gotp ls", Colour("Blue", "gotp 2"), "The main difference between the above commands is that get is a simple returning/printing of the key where without get the key is added to your clipboard and prints out a statement of the key being added to your clipboard. The simplified version (with the get key word) is for piping to other utilities.")
		fmt.Printf("%s\n%s\n%s %s %s\n\n", Colour("Green", "GET OTP VIA PROMPT"), Colour("Magenta", "gotp"), "If you only type", Colour("Blue", "gotp"), "a prompt will be brought up of the keys that have been stored. You can use this prompt to select the key you want to use.")
		fmt.Printf("%s\n%s\n%s\n%s\n%s\n", Colour("Green", "REMOVE KEYS"), Colour("Magenta", "gotp rm key"), Colour("Magenta", "gotp rm key - local"), "or you could use the index from gotp ls", Colour("Blue", "gotp rm 2"))
		return
	}
	if index, err := strconv.Atoi(args[0]); err == nil {
		getOtpByIndex(index)
		return
	}
	if args[0] == "add" {
		l := len(args)
		addToken(strings.Join(args[1:(l-1)], " "), args[l-1])
		return
	}
	if args[0] == "ls" {
		listKeys()
		return
	}
	if args[0] == "rm" {
		if index, err := strconv.Atoi(args[1]); err == nil {
			removeKeyByIndex(index)
			return
		}
		l := len(args)
		queryOtp(args[1:l], "rm")
		return
	}
	if args[0] == "get" {
		l := len(args)
		queryOtp(args[1:l], "simple")
		return
	}
	if args[0] == "lsJson" {
		listJson()
		return
	}
	if args[0] == "queryJson" {
		l := len(args)
		queryJson(args[1:l])
		return
	}
	queryOtp(args, "terminal")
}
func prompt() {
	keys := getKeyList()
	if len(keys) == 0 {
		fmt.Printf("%s\n%s\n%s", Colour("Magenta", "You don't have any otp's saved yet."), "Try adding one by typing:", Colour("Blue", "gotp add key token"))
		return
	}
	prompt := promptui.Select{
		Label: "Select a key",
		Items: keys,
	}
	_, key, err := prompt.Run()
	if err != nil {
		fmt.Printf("Prompt failed %v\n", Colour("Red", err.Error()))
		return
	}
	getOtp(key, "terminal")
}