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 }