mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-09 14:18:03 -05:00
362 lines
7.3 KiB
Go
362 lines
7.3 KiB
Go
package monero
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/noot/atomic-swap/common/rpctypes"
|
|
mcrypto "github.com/noot/atomic-swap/crypto/monero"
|
|
)
|
|
|
|
type generateFromKeysRequest struct {
|
|
Filename string `json:"filename"`
|
|
Address string `json:"address"`
|
|
SpendKey string `json:"spendkey"`
|
|
ViewKey string `json:"viewkey"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
type generateFromKeysResponse struct {
|
|
Address string `json:"address"`
|
|
Info string `json:"info"`
|
|
}
|
|
|
|
func (c *client) callGenerateFromKeys(sk *mcrypto.PrivateSpendKey, vk *mcrypto.PrivateViewKey, address mcrypto.Address,
|
|
filename, password string) error {
|
|
const (
|
|
method = "generate_from_keys"
|
|
successMessage = "Wallet has been generated successfully."
|
|
viewOnlySuccessMessage = "Watch-only wallet has been generated successfully."
|
|
)
|
|
|
|
req := &generateFromKeysRequest{
|
|
Filename: filename,
|
|
Address: string(address),
|
|
ViewKey: vk.Hex(),
|
|
Password: password,
|
|
}
|
|
|
|
if sk != nil {
|
|
req.SpendKey = sk.Hex()
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return resp.Error
|
|
}
|
|
|
|
var res *generateFromKeysResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return err
|
|
}
|
|
|
|
// TODO: check for if we passed spend key or not
|
|
if strings.Compare(successMessage, res.Info) == 0 || strings.Compare(viewOnlySuccessMessage, res.Info) == 0 {
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("got unexpected Info string: %s", res.Info)
|
|
}
|
|
|
|
// Destination represents a transfer destination
|
|
type Destination struct {
|
|
Amount uint `json:"amount"`
|
|
Address string `json:"address"`
|
|
}
|
|
|
|
type sweepAllRequest struct {
|
|
Address string `json:"address"`
|
|
AccountIndex uint `json:"account_index"`
|
|
}
|
|
|
|
// SweepAllResponse ...
|
|
type SweepAllResponse struct {
|
|
AmountList []uint `json:"amount_list"`
|
|
FeeList []uint `json:"fee_list"`
|
|
TxHashList []string `json:"tx_hash_list"`
|
|
}
|
|
|
|
func (c *client) callSweepAll(to string, accountIdx uint) (*SweepAllResponse, error) {
|
|
const (
|
|
method = "sweep_all"
|
|
)
|
|
|
|
req := &sweepAllRequest{
|
|
AccountIndex: accountIdx,
|
|
Address: to,
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return nil, resp.Error
|
|
}
|
|
|
|
var res *SweepAllResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
type transferRequest struct {
|
|
Destinations []Destination `json:"destinations"`
|
|
AccountIndex uint // optional
|
|
Priority uint `json:"priority"`
|
|
}
|
|
|
|
// TransferResponse ...
|
|
type TransferResponse struct {
|
|
Amount uint `json:"amount"`
|
|
Fee uint `json:"fee"`
|
|
MultisigTxset interface{} `json:"multisig_txset"`
|
|
TxBlob string `json:"tx_blob"`
|
|
TxHash string `json:"tx_hash"`
|
|
TxKey string `json:"tx_key"`
|
|
TxMetadata string `json:"tx_metadata"`
|
|
UnsignedTxset string `json:"unsigned_txset"`
|
|
}
|
|
|
|
func (c *client) callTransfer(destinations []Destination, accountIdx uint) (*TransferResponse, error) {
|
|
const (
|
|
method = "transfer"
|
|
)
|
|
|
|
req := &transferRequest{
|
|
Destinations: destinations,
|
|
AccountIndex: accountIdx,
|
|
Priority: 0,
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return nil, resp.Error
|
|
}
|
|
|
|
var res *TransferResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
type getBalanceRequest struct {
|
|
AccountIndex uint `json:"account_index"`
|
|
}
|
|
|
|
// GetBalanceResponse ...
|
|
type GetBalanceResponse struct {
|
|
Balance float64 `json:"balance"`
|
|
BlocksToUnlock uint `json:"blocks_to_unlock"`
|
|
UnlockedBalance float64 `json:"unlocked_balance"`
|
|
PerSubaddress []map[string]interface{} `json:"per_subaddress"`
|
|
}
|
|
|
|
func (c *client) callGetBalance(idx uint) (*GetBalanceResponse, error) {
|
|
const method = "get_balance"
|
|
|
|
req := &getBalanceRequest{
|
|
AccountIndex: idx,
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return nil, resp.Error
|
|
}
|
|
|
|
var res *GetBalanceResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// GetAddressRequest ...
|
|
type GetAddressRequest struct {
|
|
AccountIndex uint `json:"account_index"`
|
|
}
|
|
|
|
// GetAddressResponse ...
|
|
type GetAddressResponse struct {
|
|
Address string `json:"address"`
|
|
}
|
|
|
|
func (c *client) callGetAddress(idx uint) (*GetAddressResponse, error) {
|
|
const method = "get_address"
|
|
|
|
req := &GetAddressRequest{
|
|
AccountIndex: idx,
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return nil, resp.Error
|
|
}
|
|
|
|
var res *GetAddressResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// GetAccountsResponse ...
|
|
type GetAccountsResponse struct {
|
|
SubaddressAccounts []map[string]interface{} `json:"subaddress_accounts"`
|
|
}
|
|
|
|
func (c *client) callGetAccounts() (*GetAccountsResponse, error) {
|
|
const method = "get_accounts"
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, "{}")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return nil, resp.Error
|
|
}
|
|
|
|
var res *GetAccountsResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
type openWalletRequest struct {
|
|
Filename string `json:"filename"`
|
|
Password string `json:"password"`
|
|
}
|
|
|
|
func (c *client) callOpenWallet(filename, password string) error {
|
|
const method = "open_wallet"
|
|
|
|
req := &openWalletRequest{
|
|
Filename: filename,
|
|
Password: password,
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return resp.Error
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type createWalletRequest struct {
|
|
Filename string `json:"filename"`
|
|
Password string `json:"password"`
|
|
Language string `json:"language"`
|
|
}
|
|
|
|
func (c *client) callCreateWallet(filename, password string) error {
|
|
const method = "create_wallet"
|
|
|
|
req := &createWalletRequest{
|
|
Filename: filename,
|
|
Password: password,
|
|
Language: "English",
|
|
}
|
|
|
|
params, err := json.Marshal(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, string(params))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return resp.Error
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type getHeightResponse struct {
|
|
Height uint `json:"height"`
|
|
}
|
|
|
|
func (c *client) callGetHeight() (uint, error) {
|
|
const method = "get_height"
|
|
|
|
resp, err := rpctypes.PostRPC(c.endpoint, method, "{}")
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if resp.Error != nil {
|
|
return 0, resp.Error
|
|
}
|
|
|
|
var res *getHeightResponse
|
|
if err = json.Unmarshal(resp.Result, &res); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return res.Height, nil
|
|
}
|