sorare/mutations/create_direct_offer.go

152 lines
4.2 KiB
Go

package mutations
import (
"context"
"time"
"github.com/pkg/errors"
"github.com/shopspring/decimal"
"git.lehouerou.net/laurent/sorare/graphql"
"git.lehouerou.net/laurent/sorare/types"
)
type createDirectOfferInput struct {
Approvals []AuthorizationApprovalInput `json:"approvals"`
ClientMutationId string `json:"clientMutationId"`
CounteredOfferId string `json:"counteredOfferId"`
DealId string `json:"dealId"`
Duration int `json:"duration"`
ReceiveAmount AmountInput `json:"receiveAmount"`
ReceiveAssetIds []string `json:"receiveAssetIds"`
ReceiverSlug string `json:"receiverSlug"`
SendAmount AmountInput `json:"sendAmount"`
SendAssetIds []string `json:"sendAssetIds"`
}
type CreateDirectOfferParams struct {
Input createDirectOfferInput `json:"input"`
}
func (m *Mutations) newCreateDirectOfferMutation() *graphql.Mutation[BaseMutationPayload, CreateDirectOfferParams] {
return graphql.NewMutation[BaseMutationPayload, CreateDirectOfferParams](
m.c,
"createDirectOffer",
)
}
type CreateDirectOfferOptions struct {
Duration time.Duration
CounteredOfferId string
}
func WithCreateDirectOfferDuration(duration time.Duration) func(*CreateDirectOfferOptions) {
return func(o *CreateDirectOfferOptions) {
o.Duration = duration
}
}
func WithCreateDirectOfferCounteredOfferId(
counteredOfferId string,
) func(*CreateDirectOfferOptions) {
return func(o *CreateDirectOfferOptions) {
o.CounteredOfferId = counteredOfferId
}
}
func (m *Mutations) CreateDirectOffer(
ctx context.Context,
sentAmount decimal.Decimal,
sentCurrency types.SupportedCurrency,
sentAssetIds []string,
receivedAmount decimal.Decimal,
receivedCurrency types.SupportedCurrency,
receivedAssetIds []string,
privateKey string,
receiverSlug string,
options ...func(*CreateDirectOfferOptions),
) error {
opts := CreateDirectOfferOptions{
Duration: 2 * 24 * time.Hour,
CounteredOfferId: "",
}
for _, opt := range options {
opt(&opts)
}
sentCurrencyShift := 2
if sentCurrency == types.SupportedCurrencyWEI {
sentCurrencyShift = 18
}
sentAmount = sentAmount.Shift(int32(sentCurrencyShift))
receivedCurrencyShift := 2
if receivedCurrency == types.SupportedCurrencyWEI {
receivedCurrencyShift = 18
}
receivedAmount = receivedAmount.Shift(int32(receivedCurrencyShift))
prepareOfferRes, err := m.newPrepareOfferMutation().Execute(ctx, PrepareOfferParams{
Input: prepareOfferInput{
ClientMutationId: GetRandomId(),
ReceiveAmount: &AmountInput{
Amount: receivedAmount.String(),
Currency: receivedCurrency,
},
ReceiveAssetIds: receivedAssetIds,
ReceiverSlug: receiverSlug,
SendAmount: &AmountInput{
Amount: sentAmount.String(),
Currency: sentCurrency,
},
SendAssetIds: sentAssetIds,
Type: types.OfferTypeDirectOffer,
},
})
if err != nil {
return errors.Wrap(err, "preparing offer")
}
if len(prepareOfferRes.Errors) > 0 {
return errors.Wrap(errors.New(prepareOfferRes.Errors[0].Message), "preparing offer")
}
approvals, err := signAuthorizationRequests(
privateKey,
prepareOfferRes.Authorizations,
)
if err != nil {
return errors.Wrap(err, "signing authorization requests")
}
createDirectOfferRes, err := m.newCreateDirectOfferMutation().
Execute(ctx, CreateDirectOfferParams{
Input: createDirectOfferInput{
Approvals: approvals,
ClientMutationId: GetRandomId(),
CounteredOfferId: opts.CounteredOfferId,
DealId: GetRandomId(),
Duration: int(opts.Duration.Seconds()),
ReceiveAmount: AmountInput{
Amount: receivedAmount.String(),
Currency: receivedCurrency,
},
ReceiveAssetIds: receivedAssetIds,
ReceiverSlug: receiverSlug,
SendAmount: AmountInput{
Amount: sentAmount.String(),
Currency: sentCurrency,
},
SendAssetIds: sentAssetIds,
},
})
if err != nil {
return errors.Wrap(err, "creating direct offer")
}
if len(createDirectOfferRes.Errors) > 0 {
return errors.Wrap(
errors.New(createDirectOfferRes.Errors[0].Message),
"creating direct offer",
)
}
return nil
}