mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-09 14:18:03 -05:00
121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
package xmrtaker
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
ethcommon "github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/noot/atomic-swap/common"
|
|
mcrypto "github.com/noot/atomic-swap/crypto/monero"
|
|
"github.com/noot/atomic-swap/monero"
|
|
"github.com/noot/atomic-swap/protocol/backend"
|
|
|
|
logging "github.com/ipfs/go-log"
|
|
)
|
|
|
|
const (
|
|
swapDepositWallet = "swap-deposit-wallet"
|
|
)
|
|
|
|
var (
|
|
log = logging.Logger("xmrtaker")
|
|
)
|
|
|
|
// Instance implements the functionality that will be used by a user who owns ETH
|
|
// and wishes to swap for XMR.
|
|
type Instance struct {
|
|
backend backend.Backend
|
|
basepath string
|
|
|
|
walletFile, walletPassword string
|
|
transferBack bool // transfer xmr back to original account
|
|
|
|
// non-nil if a swap is currently happening, nil otherwise
|
|
swapMu sync.Mutex
|
|
swapState *swapState
|
|
}
|
|
|
|
// Config contains the configuration values for a new XMRTaker instance.
|
|
type Config struct {
|
|
Backend backend.Backend
|
|
Basepath string
|
|
MoneroWalletFile, MoneroWalletPassword string
|
|
TransferBack bool
|
|
}
|
|
|
|
// NewInstance returns a new instance of XMRTaker.
|
|
// It accepts an endpoint to a monero-wallet-rpc instance where XMRTaker will generate
|
|
// the account in which the XMR will be deposited.
|
|
func NewInstance(cfg *Config) (*Instance, error) {
|
|
var (
|
|
address mcrypto.Address
|
|
err error
|
|
)
|
|
|
|
if cfg.TransferBack {
|
|
address, err = getAddress(cfg.Backend, cfg.MoneroWalletFile, cfg.MoneroWalletPassword)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cfg.Backend.SetXMRDepositAddress(address)
|
|
}
|
|
|
|
// TODO: check that XMRTaker's monero-wallet-cli endpoint has wallet-dir configured
|
|
return &Instance{
|
|
backend: cfg.Backend,
|
|
basepath: cfg.Basepath,
|
|
walletFile: cfg.MoneroWalletFile,
|
|
walletPassword: cfg.MoneroWalletPassword,
|
|
}, nil
|
|
}
|
|
|
|
func getAddress(walletClient monero.Client, file, password string) (mcrypto.Address, error) {
|
|
// open XMR wallet, if it exists
|
|
if file != "" {
|
|
if err := walletClient.OpenWallet(file, password); err != nil {
|
|
return "", err
|
|
}
|
|
} else {
|
|
// TODO: prompt user for wallet or error if not in dev mode
|
|
log.Info("monero wallet file not set; creating wallet swap-deposit-wallet")
|
|
err := walletClient.CreateWallet(swapDepositWallet, "")
|
|
if err != nil {
|
|
if err := walletClient.OpenWallet(swapDepositWallet, ""); err != nil {
|
|
return "", fmt.Errorf("failed to create or open swap deposit wallet: %w", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// get wallet address to deposit funds into at end of swap
|
|
address, err := walletClient.GetAddress(0)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get monero wallet address: %w", err)
|
|
}
|
|
|
|
err = walletClient.CloseWallet()
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to close wallet: %w", err)
|
|
}
|
|
|
|
return mcrypto.Address(address.Address), nil
|
|
}
|
|
|
|
// Refund is called by the RPC function swap_refund.
|
|
// If it's possible to refund the ongoing swap, it does that, then notifies the counterparty.
|
|
func (a *Instance) Refund() (ethcommon.Hash, error) {
|
|
a.swapMu.Lock()
|
|
defer a.swapMu.Unlock()
|
|
|
|
if a.swapState == nil {
|
|
return ethcommon.Hash{}, errNoOngoingSwap
|
|
}
|
|
|
|
return a.swapState.doRefund()
|
|
}
|
|
|
|
// GetOngoingSwapState ...
|
|
func (a *Instance) GetOngoingSwapState() common.SwapState {
|
|
return a.swapState
|
|
}
|