-
Notifications
You must be signed in to change notification settings - Fork 14
/
preview.go
97 lines (86 loc) · 2.52 KB
/
preview.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package trade
import (
"encoding/hex"
"errors"
tradeclient "github.com/tdex-network/tdex-daemon/pkg/trade/client"
trademarket "github.com/tdex-network/tdex-daemon/pkg/trade/market"
tradetype "github.com/tdex-network/tdex-daemon/pkg/trade/type"
)
var (
// ErrInvalidMarket ...
ErrInvalidMarket = errors.New(
"market must be a pair of valid 32-bytes assets encoded in hex format",
)
// ErrInvalidTradeType ...
ErrInvalidTradeType = errors.New("trade type must be either BUY or SELL")
// ErrInvalidAmount ...
ErrInvalidAmount = errors.New("amount must be a positive satoshi amount")
)
// PreviewOpts is the struct given to Preview method
type PreviewOpts struct {
Market trademarket.Market
TradeType int
Amount uint64
Asset string
}
func (o PreviewOpts) validate() error {
if err := o.Market.Validate(); err != nil {
return err
}
if err := tradetype.TradeType(o.TradeType).Validate(); err != nil {
return err
}
if o.Amount <= 0 {
return ErrInvalidAmount
}
if buf, err := hex.DecodeString(o.Asset); err != nil || len(buf) != 32 {
return ErrInvalidAsset
}
return nil
}
// PreviewResult is the struct returned by Preview method
type PreviewResult struct {
AssetToSend string
AmountToSend uint64
AssetToReceive string
AmountToReceive uint64
}
// Preview queries the gRPC server to get the latest price for the given market,
// then calculates the amount to send or to receive depending on the given type.
func (t *Trade) Preview(opts PreviewOpts) (*PreviewResult, error) {
if err := opts.validate(); err != nil {
return nil, err
}
tradeType := tradetype.TradeType(opts.TradeType)
reply, err := t.client.PreviewTrade(tradeclient.PreviewTradeOpts{
Market: opts.Market,
TradeType: tradeType,
Amount: opts.Amount,
Asset: opts.Asset,
})
if err != nil {
return nil, err
}
preview := reply.GetPreviews()[0]
assetToSend := preview.GetAsset()
amountToSend := preview.GetAmount()
assetToReceive := opts.Asset
amountToReceive := opts.Amount
if tradeType.IsBuy() {
if opts.Asset == opts.Market.QuoteAsset {
assetToSend, assetToReceive = assetToReceive, assetToSend
amountToSend, amountToReceive = amountToReceive, amountToSend
}
} else {
if opts.Asset == opts.Market.BaseAsset {
assetToSend, assetToReceive = assetToReceive, assetToSend
amountToSend, amountToReceive = amountToReceive, amountToSend
}
}
return &PreviewResult{
AssetToSend: assetToSend,
AmountToSend: amountToSend,
AssetToReceive: assetToReceive,
AmountToReceive: amountToReceive,
}, nil
}