forked from stellar/go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
liquidity_pool_withdraw.go
133 lines (112 loc) · 3.96 KB
/
liquidity_pool_withdraw.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//lint:file-ignore U1001 Ignore all unused code, staticcheck doesn't understand testify/suite
package txnbuild
import (
"github.com/stellar/go/amount"
"github.com/stellar/go/support/errors"
"github.com/stellar/go/xdr"
)
// LiquidityPoolWithdraw represents the Stellar liquidity pool withdraw operation. See
// https://developers.stellar.org/docs/start/list-of-operations/
type LiquidityPoolWithdraw struct {
SourceAccount string
LiquidityPoolID LiquidityPoolId
Amount string
MinAmountA string
MinAmountB string
}
// NewLiquidityPoolWithdraw creates a new LiquidityPoolWithdraw operation,
// checking the ordering assets so we generate the correct pool id. Each
// AssetAmount is a pair of the asset with the minimum amount of that asset to
// withdraw.
func NewLiquidityPoolWithdraw(
sourceAccount string,
a, b AssetAmount,
amount string,
) (LiquidityPoolWithdraw, error) {
if b.Asset.LessThan(a.Asset) {
return LiquidityPoolWithdraw{}, errors.New("AssetA must be <= AssetB")
}
poolId, err := NewLiquidityPoolId(a.Asset, b.Asset)
if err != nil {
return LiquidityPoolWithdraw{}, err
}
return LiquidityPoolWithdraw{
SourceAccount: sourceAccount,
LiquidityPoolID: poolId,
Amount: amount,
MinAmountA: a.Amount,
MinAmountB: b.Amount,
}, nil
}
// BuildXDR for LiquidityPoolWithdraw returns a fully configured XDR Operation.
func (lpd *LiquidityPoolWithdraw) BuildXDR() (xdr.Operation, error) {
xdrLiquidityPoolId, err := lpd.LiquidityPoolID.ToXDR()
if err != nil {
return xdr.Operation{}, errors.Wrap(err, "couldn't build liquidity pool ID XDR")
}
xdrAmount, err := amount.Parse(lpd.Amount)
if err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'")
}
xdrMinAmountA, err := amount.Parse(lpd.MinAmountA)
if err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'MinAmountA'")
}
xdrMinAmountB, err := amount.Parse(lpd.MinAmountB)
if err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'MinAmountB'")
}
xdrOp := xdr.LiquidityPoolWithdrawOp{
LiquidityPoolId: xdrLiquidityPoolId,
Amount: xdrAmount,
MinAmountA: xdrMinAmountA,
MinAmountB: xdrMinAmountB,
}
opType := xdr.OperationTypeLiquidityPoolWithdraw
body, err := xdr.NewOperationBody(opType, xdrOp)
if err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to build XDR OperationBody")
}
op := xdr.Operation{Body: body}
SetOpSourceAccount(&op, lpd.SourceAccount)
return op, nil
}
// FromXDR for LiquidityPoolWithdraw initializes the txnbuild struct from the corresponding xdr Operation.
func (lpd *LiquidityPoolWithdraw) FromXDR(xdrOp xdr.Operation) error {
result, ok := xdrOp.Body.GetLiquidityPoolWithdrawOp()
if !ok {
return errors.New("error parsing liquidity_pool_withdraw operation from xdr")
}
liquidityPoolID, err := liquidityPoolIdFromXDR(result.LiquidityPoolId)
if err != nil {
return errors.New("error parsing LiquidityPoolId in liquidity_pool_withdraw operation from xdr")
}
lpd.LiquidityPoolID = liquidityPoolID
lpd.SourceAccount = accountFromXDR(xdrOp.SourceAccount)
lpd.Amount = amount.String(result.Amount)
lpd.MinAmountA = amount.String(result.MinAmountA)
lpd.MinAmountB = amount.String(result.MinAmountB)
return nil
}
// Validate for LiquidityPoolWithdraw validates the required struct fields. It returns an error if any of the fields are
// invalid. Otherwise, it returns nil.
func (lpd *LiquidityPoolWithdraw) Validate() error {
err := validateAmount(lpd.Amount)
if err != nil {
return NewValidationError("Amount", err.Error())
}
err = validateAmount(lpd.MinAmountA)
if err != nil {
return NewValidationError("MinAmountA", err.Error())
}
err = validateAmount(lpd.MinAmountB)
if err != nil {
return NewValidationError("MinAmountB", err.Error())
}
return nil
}
// GetSourceAccount returns the source account of the operation, or nil if not
// set.
func (lpd *LiquidityPoolWithdraw) GetSourceAccount() string {
return lpd.SourceAccount
}