code.vegaprotocol.io/vega@v0.79.0/datanode/entities/liquidity_provision.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package entities 17 18 import ( 19 "encoding/json" 20 "fmt" 21 "time" 22 23 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 24 "code.vegaprotocol.io/vega/protos/vega" 25 26 "github.com/jackc/pgtype" 27 "github.com/shopspring/decimal" 28 "google.golang.org/protobuf/encoding/protojson" 29 ) 30 31 type _LiquidityProvision struct{} 32 33 type LiquidityProvisionID = ID[_LiquidityProvision] 34 35 type LiquidityOrderReference struct { 36 *vega.LiquidityOrderReference 37 } 38 39 func (l LiquidityOrderReference) EncodeBinary(_ *pgtype.ConnInfo, buf []byte) ([]byte, error) { 40 protoBytes, err := protojson.Marshal(l.LiquidityOrderReference) 41 if err != nil { 42 return buf, fmt.Errorf("failed to marshal LiquidityOrderReference: %w", err) 43 } 44 return append(buf, protoBytes...), nil 45 } 46 47 func (l *LiquidityOrderReference) DecodeBinary(_ *pgtype.ConnInfo, src []byte) error { 48 return protojson.Unmarshal(src, l) 49 } 50 51 type LiquidityProvision struct { 52 ID LiquidityProvisionID 53 PartyID PartyID 54 CreatedAt time.Time 55 UpdatedAt time.Time 56 MarketID MarketID 57 CommitmentAmount decimal.Decimal 58 Fee decimal.Decimal 59 Sells []LiquidityOrderReference 60 Buys []LiquidityOrderReference 61 Version int64 62 Status LiquidityProvisionStatus 63 Reference string 64 TxHash TxHash 65 VegaTime time.Time 66 } 67 68 type CurrentAndPreviousLiquidityProvisions struct { 69 ID LiquidityProvisionID 70 PartyID PartyID 71 CreatedAt time.Time 72 UpdatedAt time.Time 73 MarketID MarketID 74 CommitmentAmount decimal.Decimal 75 Fee decimal.Decimal 76 Sells []LiquidityOrderReference 77 Buys []LiquidityOrderReference 78 Version int64 79 Status LiquidityProvisionStatus 80 Reference string 81 TxHash TxHash 82 VegaTime time.Time 83 PreviousID LiquidityProvisionID 84 PreviousPartyID PartyID 85 PreviousCreatedAt *time.Time 86 PreviousUpdatedAt *time.Time 87 PreviousMarketID MarketID 88 PreviousCommitmentAmount *decimal.Decimal 89 PreviousFee *decimal.Decimal 90 PreviousSells []LiquidityOrderReference 91 PreviousBuys []LiquidityOrderReference 92 PreviousVersion *int64 93 PreviousStatus *LiquidityProvisionStatus 94 PreviousReference *string 95 PreviousTxHash TxHash 96 PreviousVegaTime *time.Time 97 } 98 99 func LiquidityProvisionFromProto(lpProto *vega.LiquidityProvision, txHash TxHash, vegaTime time.Time) (LiquidityProvision, error) { 100 lpID := LiquidityProvisionID(lpProto.Id) 101 partyID := PartyID(lpProto.PartyId) 102 marketID := MarketID(lpProto.MarketId) 103 104 commitmentAmount, err := decimal.NewFromString(lpProto.CommitmentAmount) 105 if err != nil { 106 return LiquidityProvision{}, fmt.Errorf("liquidity provision has invalid commitement amount: %w", err) 107 } 108 109 fee, err := decimal.NewFromString(lpProto.Fee) 110 if err != nil { 111 return LiquidityProvision{}, fmt.Errorf("liquidity provision has invalid fee amount: %w", err) 112 } 113 114 sells := make([]LiquidityOrderReference, 0, len(lpProto.Sells)) 115 buys := make([]LiquidityOrderReference, 0, len(lpProto.Buys)) 116 117 for _, sell := range lpProto.Sells { 118 sells = append(sells, LiquidityOrderReference{sell}) 119 } 120 121 for _, buy := range lpProto.Buys { 122 buys = append(buys, LiquidityOrderReference{buy}) 123 } 124 125 return LiquidityProvision{ 126 ID: lpID, 127 PartyID: partyID, 128 CreatedAt: NanosToPostgresTimestamp(lpProto.CreatedAt), 129 UpdatedAt: NanosToPostgresTimestamp(lpProto.UpdatedAt), 130 MarketID: marketID, 131 CommitmentAmount: commitmentAmount, 132 Fee: fee, 133 Sells: sells, 134 Buys: buys, 135 Version: int64(lpProto.Version), 136 Status: LiquidityProvisionStatus(lpProto.Status), 137 Reference: lpProto.Reference, 138 TxHash: txHash, 139 VegaTime: vegaTime, 140 }, nil 141 } 142 143 func (lp LiquidityProvision) ToProto() *vega.LiquidityProvision { 144 sells := make([]*vega.LiquidityOrderReference, 0, len(lp.Sells)) 145 buys := make([]*vega.LiquidityOrderReference, 0, len(lp.Buys)) 146 147 for _, sell := range lp.Sells { 148 sells = append(sells, sell.LiquidityOrderReference) 149 } 150 for _, buy := range lp.Buys { 151 buys = append(buys, buy.LiquidityOrderReference) 152 } 153 154 return &vega.LiquidityProvision{ 155 Id: lp.ID.String(), 156 PartyId: lp.PartyID.String(), 157 CreatedAt: lp.CreatedAt.UnixNano(), 158 UpdatedAt: lp.UpdatedAt.UnixNano(), 159 MarketId: lp.MarketID.String(), 160 CommitmentAmount: lp.CommitmentAmount.String(), 161 Fee: lp.Fee.String(), 162 Sells: sells, 163 Buys: buys, 164 Version: uint64(lp.Version), 165 Status: vega.LiquidityProvision_Status(lp.Status), 166 Reference: lp.Reference, 167 } 168 } 169 170 func (lp CurrentAndPreviousLiquidityProvisions) ToProto() *v2.LiquidityProvision { 171 sells := make([]*vega.LiquidityOrderReference, 0) 172 buys := make([]*vega.LiquidityOrderReference, 0) 173 174 for _, sell := range lp.Sells { 175 sells = append(sells, sell.LiquidityOrderReference) 176 } 177 for _, buy := range lp.Buys { 178 buys = append(buys, buy.LiquidityOrderReference) 179 } 180 181 if lp.Status == LiquidityProvisionStatusPending && (lp.PreviousStatus != nil && *lp.PreviousStatus == LiquidityProvisionStatusActive) { 182 // check to see if the previous state is active, if so, then that is still the active state, 183 // and the current state is pending 184 return lp.currentWithPendingLP(sells, buys) 185 } 186 187 return &v2.LiquidityProvision{ 188 Current: &vega.LiquidityProvision{ 189 Id: lp.ID.String(), 190 PartyId: lp.PartyID.String(), 191 CreatedAt: lp.CreatedAt.UnixNano(), 192 UpdatedAt: lp.UpdatedAt.UnixNano(), 193 MarketId: lp.MarketID.String(), 194 CommitmentAmount: lp.CommitmentAmount.String(), 195 Fee: lp.Fee.String(), 196 Sells: sells, 197 Buys: buys, 198 Version: uint64(lp.Version), 199 Status: vega.LiquidityProvision_Status(lp.Status), 200 Reference: lp.Reference, 201 }, 202 } 203 } 204 205 func (lp CurrentAndPreviousLiquidityProvisions) currentWithPendingLP(sells, buys []*vega.LiquidityOrderReference) *v2.LiquidityProvision { 206 previousSells := make([]*vega.LiquidityOrderReference, 0) 207 previousBuys := make([]*vega.LiquidityOrderReference, 0) 208 209 if lp.PreviousSells != nil { 210 for _, sell := range lp.PreviousSells { 211 previousSells = append(previousSells, sell.LiquidityOrderReference) 212 } 213 } 214 if lp.PreviousBuys != nil { 215 for _, buy := range lp.PreviousBuys { 216 previousBuys = append(previousBuys, buy.LiquidityOrderReference) 217 } 218 } 219 pending := vega.LiquidityProvision{ 220 Id: lp.ID.String(), 221 PartyId: lp.PartyID.String(), 222 CreatedAt: lp.CreatedAt.UnixNano(), 223 UpdatedAt: lp.UpdatedAt.UnixNano(), 224 MarketId: lp.MarketID.String(), 225 CommitmentAmount: lp.CommitmentAmount.String(), 226 Fee: lp.Fee.String(), 227 Sells: sells, 228 Buys: buys, 229 Version: uint64(lp.Version), 230 Status: vega.LiquidityProvision_Status(lp.Status), 231 Reference: lp.Reference, 232 } 233 234 return &v2.LiquidityProvision{ 235 Current: &vega.LiquidityProvision{ 236 Id: (lp.PreviousID).String(), 237 PartyId: (lp.PreviousPartyID).String(), 238 CreatedAt: (lp.PreviousCreatedAt).UnixNano(), 239 UpdatedAt: (lp.PreviousUpdatedAt).UnixNano(), 240 MarketId: (lp.PreviousMarketID).String(), 241 CommitmentAmount: (lp.PreviousCommitmentAmount).String(), 242 Fee: (lp.PreviousFee).String(), 243 Sells: previousSells, 244 Buys: previousBuys, 245 Version: uint64(*lp.PreviousVersion), 246 Status: vega.LiquidityProvision_Status(*lp.PreviousStatus), 247 Reference: *lp.PreviousReference, 248 }, 249 Pending: &pending, 250 } 251 } 252 253 type LiquidityProvisionKey struct { 254 ID LiquidityProvisionID 255 VegaTime time.Time 256 } 257 258 func (lp LiquidityProvision) Key() LiquidityProvisionKey { 259 return LiquidityProvisionKey{lp.ID, lp.VegaTime} 260 } 261 262 var LiquidityProvisionColumns = []string{ 263 "id", "party_id", "created_at", "updated_at", "market_id", 264 "commitment_amount", "fee", "sells", "buys", "version", 265 "status", "reference", "tx_hash", "vega_time", 266 } 267 268 func (lp LiquidityProvision) ToRow() []interface{} { 269 return []interface{}{ 270 lp.ID, lp.PartyID, lp.CreatedAt, lp.UpdatedAt, lp.MarketID, 271 lp.CommitmentAmount, lp.Fee, lp.Sells, lp.Buys, lp.Version, 272 lp.Status, lp.Reference, lp.TxHash, lp.VegaTime, 273 } 274 } 275 276 func (lp LiquidityProvision) Cursor() *Cursor { 277 lc := LiquidityProvisionCursor{ 278 VegaTime: lp.VegaTime, 279 ID: lp.ID, 280 } 281 return NewCursor(lc.String()) 282 } 283 284 func (lp CurrentAndPreviousLiquidityProvisions) Cursor() *Cursor { 285 lc := LiquidityProvisionCursor{ 286 VegaTime: lp.VegaTime, 287 ID: lp.ID, 288 } 289 return NewCursor(lc.String()) 290 } 291 292 func (lp LiquidityProvision) ToProtoEdge(_ ...any) (*v2.LiquidityProvisionsEdge, error) { 293 return &v2.LiquidityProvisionsEdge{ 294 Node: lp.ToProto(), 295 Cursor: lp.Cursor().Encode(), 296 }, nil 297 } 298 299 func (lp CurrentAndPreviousLiquidityProvisions) ToProtoEdge(_ ...any) (*v2.LiquidityProvisionWithPendingEdge, error) { 300 return &v2.LiquidityProvisionWithPendingEdge{ 301 Node: lp.ToProto(), 302 Cursor: lp.Cursor().Encode(), 303 }, nil 304 } 305 306 type LiquidityProvisionCursor struct { 307 VegaTime time.Time `json:"vegaTime"` 308 ID LiquidityProvisionID `json:"id"` 309 } 310 311 func (lc LiquidityProvisionCursor) String() string { 312 bs, err := json.Marshal(lc) 313 if err != nil { 314 panic(fmt.Errorf("could not marshal liquidity provision cursor: %w", err)) 315 } 316 return string(bs) 317 } 318 319 func (lc *LiquidityProvisionCursor) Parse(cursorString string) error { 320 if cursorString == "" { 321 return nil 322 } 323 return json.Unmarshal([]byte(cursorString), lc) 324 }