sorare/mutations/bid.go

114 lines
2.8 KiB
Go

package mutations
import (
"context"
gql "github.com/llehouerou/go-graphql-client"
"github.com/pkg/errors"
"github.com/shopspring/decimal"
"git.lehouerou.net/laurent/sorare/graphql"
"git.lehouerou.net/laurent/sorare/types"
)
type bidInput struct {
Approvals []AuthorizationApprovalInput `json:"approvals"`
AuctionId string `json:"auctionId"`
Amount decimal.Decimal `json:"amount"`
SettlementInfo SettlementInfo `json:"settlementInfo"`
ClientMutationId string `json:"clientMutationId"`
}
type BidPayload struct {
Bid struct {
Id graphql.Id `graphql:"id"`
} `graphql:"bid"`
BaseMutationPayload
}
type BidParams struct {
Input bidInput `graphql:"input"`
}
func (m *Mutations) newBidMutation() *graphql.Mutation[BidPayload, BidParams] {
return graphql.NewMutation[BidPayload, BidParams](m.c, "bid")
}
type BidOptions struct {
PaymentMethod types.PaymentMethod
}
func WithBidPaymentMethod(paymentMethod types.PaymentMethod) func(*BidOptions) {
return func(o *BidOptions) {
o.PaymentMethod = paymentMethod
}
}
func (m *Mutations) BidOnAuction(
ctx context.Context,
auctionId string,
amount decimal.Decimal,
currency types.SupportedCurrency,
privateKey string,
options ...func(*BidOptions),
) (string, error) {
opts := BidOptions{
PaymentMethod: types.PaymentMethodWallet,
}
for _, opt := range options {
opt(&opts)
}
exchangeRate, err := m.ExchangeRate.Get(ctx, graphql.EmptyParams{})
if err != nil {
return "", errors.Wrap(err, "getting exchange rate")
}
si := SettlementInfo{
Currency: currency,
PaymentMethod: opts.PaymentMethod,
ExchangeRateId: exchangeRate.Id.String(),
}
currencyShift := 2
if currency == types.SupportedCurrencyWEI {
currencyShift = 18
}
amount = amount.Shift(int32(currencyShift))
prepareBidRes, err := m.newPrepareBidMutation().Execute(ctx, PrepareBidParams{
Input: prepareBidInput{
AuctionId: gql.ID(auctionId),
Amount: amount,
SettlementInfo: si,
}})
if err != nil {
return "", errors.Wrap(err, "preparing bid")
}
if len(prepareBidRes.Errors) > 0 {
return "", errors.Wrap(errors.New(prepareBidRes.Errors[0].Message), "preparing bid")
}
approvals, err := signAuthorizationRequests(
privateKey,
prepareBidRes.Authorizations,
)
if err != nil {
return "", errors.Wrap(err, "signing authorization requests")
}
bidRes, err := m.newBidMutation().Execute(ctx, BidParams{
Input: bidInput{
Approvals: approvals,
AuctionId: auctionId,
Amount: amount,
SettlementInfo: si,
ClientMutationId: GetRandomId(),
}})
if err != nil {
return "", errors.Wrap(err, "placing bid")
}
if len(bidRes.Errors) > 0 {
return "", errors.Wrap(errors.New(bidRes.Errors[0].Message), "placing bid")
}
return bidRes.Bid.Id.String(), nil
}