dero-swaps/swap_manager.go

174 lines
4.6 KiB
Go
Raw Normal View History

2024-04-11 13:35:17 +01:00
package main
import (
"dero-swap/coin"
"dero-swap/dero"
"dero-swap/monero"
"encoding/json"
"fmt"
"io/fs"
"log"
"os"
"time"
"github.com/deroproject/derohe/rpc"
)
func Swap_Controller() {
var file_data []byte
var swap_e coin.Swap_Entry
var expired, fails, sent, active uint
var txs []rpc.Transfer
var xmr_txs []monero.RPC_XMR_Transfer_Params
var dir_entries []fs.DirEntry
var err error
for {
time.Sleep(time.Minute)
dir_entries, err = os.ReadDir("swaps/active")
expired = 0
fails = 0
sent = 0
active = 0
txs = nil
xmr_txs = nil
for _, e := range dir_entries {
active++
file_data = nil
err = nil
file_data, err = os.ReadFile("swaps/active/" + e.Name())
if err != nil {
fails++
continue
}
err = json.Unmarshal(file_data, &swap_e)
if err != nil {
fails++
continue
}
creation_t := time.UnixMilli(swap_e.Created)
// if there was no deposit, mark the request as expired
if swap_e.Status == 0 && time.Since(creation_t) > time.Hour {
os.WriteFile(fmt.Sprintf("swaps/expired/%d", swap_e.Created), file_data, 0644)
os.Remove("swaps/active/" + e.Name())
switch swap_e.Coin {
case coin.LTCDERO, coin.BTCDERO, coin.ARRRDERO, coin.XMRDERO:
coin.Locked.RemoveLockedBalance(swap_e.Coin, swap_e.Amount)
default:
coin.Locked.RemoveLockedBalance(swap_e.Coin, swap_e.Price)
}
expired++
continue
}
var found_deposit, visible bool
// check for deposits
switch swap_e.Coin {
case coin.BTCDERO, coin.LTCDERO, coin.ARRRDERO:
found_deposit, visible, _, err = coin.XTCListReceivedByAddress(swap_e.Coin, swap_e.Wallet, swap_e.Price, swap_e.Block, false)
case coin.XMRDERO:
if payment_id := monero.SplitIntegratedAddress(swap_e.Wallet); payment_id != "" {
found_deposit = monero.XMRGetTX(payment_id, swap_e.Block)
visible = found_deposit
} else {
log.Println("Can't split intragrated XMR address")
}
default:
found_deposit = dero.CheckIncomingTransfers(uint64(swap_e.Created), swap_e.Block)
visible = found_deposit
}
if err != nil {
log.Printf("Error checking incoming %s transactions\n", swap_e.Coin)
fails++
continue
}
// mark request as done
if swap_e.Status == 2 {
err = os.WriteFile(fmt.Sprintf("swaps/done/%d", swap_e.Created), file_data, 0644)
if err != nil {
log.Printf("Can't mark swap as done, swap %d, err %v\n", swap_e.Created, err)
} else {
os.Remove("swaps/active/" + e.Name())
}
}
// start payout if there are at least 2 confirmations
// requests won't be marked as expired, if there is already 1 confirmation
if visible {
if found_deposit && swap_e.Status <= 1 {
// create transaction
log.Printf("Found deposit for ID %d (%s): %.8f coins; adding to payout TX\n", swap_e.Created, swap_e.Coin, swap_e.Amount)
switch swap_e.Coin {
case coin.DEROLTC, coin.DEROBTC:
log.Println("Starting LTC/BTC payout")
_, txid := coin.XTCSend(swap_e.Coin, swap_e.Destination, swap_e.Price)
log.Printf("LTC TXID: %s\n", txid)
coin.Locked.RemoveLockedBalance(swap_e.Coin, swap_e.Price)
case coin.DEROARRR:
log.Println("Starting ARRR payout")
ok, result := coin.ARRR_Send(swap_e.Destination, swap_e.Price)
log.Printf("ARRR status: %v, %s\n", ok, result)
coin.Locked.RemoveLockedBalance(swap_e.Coin, swap_e.Price)
case coin.DEROXMR:
xmr_txs = append(xmr_txs, monero.AddTX(swap_e.Destination, swap_e.Price))
default:
txs = append(txs, dero.AddTX(swap_e.Destination, swap_e.Amount))
}
swap_e.Status = 2
sent++
active--
} else {
// transaction was confirmed
swap_e.Status = 1
}
json_data, _ := json.Marshal(&swap_e)
os.WriteFile("swaps/active/"+e.Name(), json_data, 0644)
if swap_e.Status == 2 {
err = os.WriteFile(fmt.Sprintf("swaps/done/%d", swap_e.Created), file_data, 0644)
if err != nil {
log.Printf("Can't mark swap as done, swap %d, err %v\n", swap_e.Created, err)
} else {
os.Remove("swaps/active/" + e.Name())
}
}
}
}
// Dero and Monero payout process
if len(txs) > 0 {
log.Println("Starting DERO payout process")
dero.Payout(txs)
}
// TODO: create function and TX verification
if len(xmr_txs) > 0 {
log.Println("Starting XMR payout process")
if ok, txid := monero.XMRSend(xmr_txs); ok {
log.Printf("XMR transaction (TXID %s) successfully sent\n", txid)
} else {
log.Println("Error sending XMR transaction")
}
}
if sent+expired+fails > 0 {
log.Printf("Swap processing: %d sent, %d expired, %d errors\n", sent, expired, fails)
}
}
}