diff --git a/client/webserver/api.go b/client/webserver/api.go index 2e56a8a9ea..6c107f4fa5 100644 --- a/client/webserver/api.go +++ b/client/webserver/api.go @@ -29,7 +29,7 @@ func (s *WebServer) apiDiscoverAccount(w http.ResponseWriter, r *http.Request) { s.writeAPIError(w, fmt.Errorf("password error: %w", err)) return } - exchangeInfo, paid, err := s.core.DiscoverAccount(form.Addr, pass, cert) + exchangeInfo, paid, err := s.core.DiscoverAccount(form.Addr, pass, cert) // TODO: update when paid return removed if err != nil { s.writeAPIError(w, err) return @@ -115,7 +115,6 @@ func (s *WebServer) apiRegister(w http.ResponseWriter, r *http.Request) { Addr: reg.Addr, Cert: []byte(reg.Cert), AppPass: pass, - Fee: reg.Fee, Asset: &assetID, }) if err != nil { @@ -128,6 +127,41 @@ func (s *WebServer) apiRegister(w http.ResponseWriter, r *http.Request) { writeJSON(w, simpleAck(), s.indent) } +// apiPostBond is the handler for the '/postbond' API request. +func (s *WebServer) apiPostBond(w http.ResponseWriter, r *http.Request) { + post := new(postBondForm) + defer post.Password.Clear() + if !readPost(w, r, post) { + return + } + assetID := uint32(42) + if post.AssetID != nil { + assetID = *post.AssetID + } + wallet := s.core.WalletState(assetID) + if wallet == nil { + s.writeAPIError(w, errors.New("no wallet")) + return + } + + _, err := s.core.PostBond(&core.PostBondForm{ + Addr: post.Addr, + Cert: []byte(post.Cert), + AppPass: post.Password, + Bond: post.Bond, + Asset: &assetID, + LockTime: post.LockTime, + }) + if err != nil { + s.writeAPIError(w, fmt.Errorf("add bond error: %w", err)) + return + } + // There was no error paying the fee, but we must wait on confirmations + // before informing the DEX of the fee payment. Those results will come + // through as a notification. + writeJSON(w, simpleAck(), s.indent) +} + // apiNewWallet is the handler for the '/newwallet' API request. func (s *WebServer) apiNewWallet(w http.ResponseWriter, r *http.Request) { form := new(newWalletForm) @@ -304,7 +338,7 @@ func (s *WebServer) apiAccountExport(w http.ResponseWriter, r *http.Request) { s.writeAPIError(w, fmt.Errorf("password error: %w", err)) return } - account, err := s.core.AccountExport(pass, form.Host) + account, _, err := s.core.AccountExport(pass, form.Host) if err != nil { s.writeAPIError(w, fmt.Errorf("error exporting account: %w", err)) return @@ -313,9 +347,11 @@ func (s *WebServer) apiAccountExport(w http.ResponseWriter, r *http.Request) { res := &struct { OK bool `json:"ok"` Account *core.Account `json:"account"` + Bonds []*db.Bond `json:"bonds"` }{ OK: true, Account: account, + // Bonds TODO } writeJSON(w, res, s.indent) } @@ -356,7 +392,7 @@ func (s *WebServer) apiAccountImport(w http.ResponseWriter, r *http.Request) { s.writeAPIError(w, fmt.Errorf("password error: %w", err)) return } - err = s.core.AccountImport(pass, form.Account) + err = s.core.AccountImport(pass, form.Account, nil /* Bonds TODO */) if err != nil { s.writeAPIError(w, fmt.Errorf("error importing account: %w", err)) return diff --git a/client/webserver/live_test.go b/client/webserver/live_test.go index 0c7ee8ce30..bd4bc9b5ac 100644 --- a/client/webserver/live_test.go +++ b/client/webserver/live_test.go @@ -524,6 +524,9 @@ func (c *TCore) Register(r *core.RegisterForm) (*core.RegisterResult, error) { c.reg = r return nil, nil } +func (c *TCore) PostBond(r *core.PostBondForm) (*core.PostBondResult, error) { + return nil, nil +} func (c *TCore) EstimateRegistrationTxFee(host string, certI interface{}, assetID uint32) (uint64, error) { return 0, nil } @@ -664,10 +667,10 @@ func (c *TCore) PreOrder(*core.TradeForm) (*core.OrderEstimate, error) { }, nil } -func (c *TCore) AccountExport(pw []byte, host string) (*core.Account, error) { - return nil, nil +func (c *TCore) AccountExport(pw []byte, host string) (*core.Account, []*db.Bond, error) { + return nil, nil, nil } -func (c *TCore) AccountImport(pw []byte, account core.Account) error { +func (c *TCore) AccountImport(pw []byte, account *core.Account, bond []*db.Bond) error { return nil } func (c *TCore) AccountDisable(pw []byte, host string) error { return nil } diff --git a/client/webserver/types.go b/client/webserver/types.go index a35aa3337b..9cbe027924 100644 --- a/client/webserver/types.go +++ b/client/webserver/types.go @@ -41,8 +41,17 @@ type registrationForm struct { Addr string `json:"addr"` Cert string `json:"cert"` Password encode.PassBytes `json:"pass"` - Fee uint64 `json:"fee"` - AssetID *uint32 `json:"asset,omitempty"` // prevent out-of-date frontend from paying fee in BTC + AssetID *uint32 `json:"asset,omitempty"` // prevent omission using BTC +} + +// postBondForm is used to post a new bond for an existing DEX account. +type postBondForm struct { + Addr string `json:"addr"` + Cert string `json:"cert"` // may be empty for adding bond to existing account + Password encode.PassBytes `json:"pass"` + Bond uint64 `json:"bond"` + AssetID *uint32 `json:"asset,omitempty"` // prevent omission using BTC + LockTime uint64 `json:"lockTime"` } type registrationTxFeeForm struct { @@ -93,7 +102,7 @@ type accountExportForm struct { type accountImportForm struct { Pass encode.PassBytes `json:"pw"` - Account core.Account `json:"account"` + Account *core.Account `json:"account"` } type accountDisableForm struct { diff --git a/client/webserver/webserver.go b/client/webserver/webserver.go index 2e5d78638e..7d55b95eab 100644 --- a/client/webserver/webserver.go +++ b/client/webserver/webserver.go @@ -22,6 +22,7 @@ import ( "decred.org/dcrdex/client/asset" "decred.org/dcrdex/client/core" + "decred.org/dcrdex/client/db" "decred.org/dcrdex/client/websocket" "decred.org/dcrdex/dex" "decred.org/dcrdex/dex/encode" @@ -76,6 +77,7 @@ type clientCore interface { Network() dex.Network Exchanges() map[string]*core.Exchange Register(*core.RegisterForm) (*core.RegisterResult, error) + PostBond(form *core.PostBondForm) (*core.PostBondResult, error) Login(pw []byte) (*core.LoginResult, error) InitializeClient(pw, seed []byte) error AssetBalance(assetID uint32) (*core.WalletBalance, error) @@ -104,8 +106,8 @@ type clientCore interface { Order(oid dex.Bytes) (*core.Order, error) MaxBuy(host string, base, quote uint32, rate uint64) (*core.MaxOrderEstimate, error) MaxSell(host string, base, quote uint32) (*core.MaxOrderEstimate, error) - AccountExport(pw []byte, host string) (*core.Account, error) - AccountImport(pw []byte, account core.Account) error + AccountExport(pw []byte, host string) (*core.Account, []*db.Bond, error) + AccountImport(pw []byte, account *core.Account, bonds []*db.Bond) error AccountDisable(pw []byte, host string) error IsInitialized() bool ExportSeed(pw []byte) ([]byte, error) @@ -318,6 +320,7 @@ func New(cfg *Config) (*WebServer, error) { apiAuth.Get("/user", s.apiUser) apiAuth.Post("/defaultwalletcfg", s.apiDefaultWalletCfg) apiAuth.Post("/register", s.apiRegister) + apiAuth.Post("/postbond", s.apiPostBond) apiAuth.Post("/newwallet", s.apiNewWallet) apiAuth.Post("/openwallet", s.apiOpenWallet) apiAuth.Post("/depositaddress", s.apiNewDepositAddress) diff --git a/client/webserver/webserver_test.go b/client/webserver/webserver_test.go index e70557cf78..d7be600ab5 100644 --- a/client/webserver/webserver_test.go +++ b/client/webserver/webserver_test.go @@ -18,6 +18,7 @@ import ( "decred.org/dcrdex/client/asset" "decred.org/dcrdex/client/core" + "decred.org/dcrdex/client/db" "decred.org/dcrdex/dex" "decred.org/dcrdex/dex/encode" "decred.org/dcrdex/dex/order" @@ -57,6 +58,7 @@ type TCore struct { syncFeed core.BookFeed syncErr error regErr error + postBondErr error loginErr error logoutErr error initErr error @@ -81,6 +83,9 @@ func (c *TCore) DiscoverAccount(dexAddr string, pw []byte, certI interface{}) (* return nil, false, nil } func (c *TCore) Register(r *core.RegisterForm) (*core.RegisterResult, error) { return nil, c.regErr } +func (c *TCore) PostBond(r *core.PostBondForm) (*core.PostBondResult, error) { + return nil, c.postBondErr +} func (c *TCore) EstimateRegistrationTxFee(host string, certI interface{}, assetID uint32) (uint64, error) { return 0, nil } @@ -163,10 +168,10 @@ func (c *TCore) MaxSell(host string, base, quote uint32) (*core.MaxOrderEstimate func (c *TCore) PreOrder(*core.TradeForm) (*core.OrderEstimate, error) { return nil, nil } -func (c *TCore) AccountExport(pw []byte, host string) (*core.Account, error) { - return nil, nil +func (c *TCore) AccountExport(pw []byte, host string) (*core.Account, []*db.Bond, error) { + return nil, nil, nil } -func (c *TCore) AccountImport(pw []byte, account core.Account) error { +func (c *TCore) AccountImport(pw []byte, account *core.Account, bonds []*db.Bond) error { return nil } func (c *TCore) AccountDisable(pw []byte, host string) error { return nil }