package main import ( "cwtch.im/tapir/persistence" "cwtch.im/tapir/primitives/privacypass" "encoding/base64" "encoding/json" "git.openprivacy.ca/openprivacy/libricochet-go/log" "git.openprivacy.ca/openprivacy/zcashrpc" "git.openprivacy.ca/openprivacy/zcashtokenservice" "io/ioutil" "strings" "time" ) type ZcashConfig struct { Username string `json: "username"` Password string `json: "password"` ZAddress string `json: "zaddress"` } type TapirServer struct { tokenServer *privacypass.TokenServer db persistence.Service } func StartTapirServer() *TapirServer { ts := new(TapirServer) ts.db = new(persistence.BoltPersistence) ts.db.Open("tokens.db") ts.tokenServer = privacypass.NewTokenServerFromStore(ts.db) ts.db.Setup([]string{"transactions"}) return ts } func (ts *TapirServer) Refresh() { for { configFile, _ := ioutil.ReadFile("config.json") config := ZcashConfig{} _ = json.Unmarshal(configFile, &config) zc := zcashrpc.NewLocalClient(config.Username, config.Password) transactions, err := zc.ListReceivedTransactionsByAddress(config.ZAddress) if err != nil { log.Errorf("Error fetching zcash transactions: %v", err) } for _, transaction := range transactions { exists, _ := ts.db.Check("transactions", transaction.TransactionID) // Only process transactions we haven't seen before, and that meet the cost requirement if !exists && transaction.Amount >= 0.1 { log.Infof("Got a new transaction txid:%s, amount %f", transaction.TransactionID, transaction.Amount) decodedMemo, _ := transaction.Memo.Decode() decodedMemoStr := strings.Trim(string(decodedMemo), "\000") response, returnAddress := zcashtokenservice.ProcessRequest(decodedMemoStr, config.ZAddress, ts.tokenServer) if returnAddress != "" { log.Infof("Sending Response: %v", response) // We send a memo back with a very low memo cost (covered by the initial request) zc.SendOne(config.ZAddress, returnAddress, response, 0.001) } else { error, err := base64.StdEncoding.DecodeString(response) log.Infof("Error: %s %v", error, err) } ts.db.Persist("transactions", transaction.TransactionID, transaction) } } time.Sleep(time.Second * 10) } } func main() { log.SetLevel(log.LevelDebug) ts := StartTapirServer() log.Infof("Token Server Public Key: %v", ts.tokenServer.Y) ts.Refresh() }