sorare/mutations/create_single_sale_offer.go

149 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 createSingleSaleOfferInput struct {
Approvals []AuthorizationApprovalInput `json:"approvals"`
AssetId string `json:"assetId"`
ClientMutationId string `json:"clientMutationId"`
DealId string `json:"dealId"`
Duration int `json:"duration"`
ReceiveAmount AmountInput `json:"receiveAmount"`
SettlementCurrencies []types.SupportedCurrency `json:"settlementCurrencies"`
StartDate string `json:"startDate"`
}
type CreateSingleSaleOfferParams struct {
Input createSingleSaleOfferInput `graphql:"input"`
}
func (m *Mutations) newCreateSingleSaleOfferMutation() *graphql.Mutation[BaseMutationPayload, CreateSingleSaleOfferParams] {
return graphql.NewMutation[BaseMutationPayload, CreateSingleSaleOfferParams](
m.c,
"createSingleSaleOffer",
)
}
type CreateSingleSaleOfferOptions struct {
Duration time.Duration
DelayBeforeStart time.Duration
SettlementCurrencies []types.SupportedCurrency
}
func WithDuration(duration time.Duration) func(*CreateSingleSaleOfferOptions) {
return func(o *CreateSingleSaleOfferOptions) {
o.Duration = duration
}
}
func WithDelayBeforeStart(delay time.Duration) func(*CreateSingleSaleOfferOptions) {
return func(o *CreateSingleSaleOfferOptions) {
o.DelayBeforeStart = delay
}
}
func WithSettlementCurrencies(
currencies []types.SupportedCurrency,
) func(*CreateSingleSaleOfferOptions) {
return func(o *CreateSingleSaleOfferOptions) {
o.SettlementCurrencies = currencies
}
}
func (m *Mutations) CreateSingleSaleOffer(
ctx context.Context,
assetId string,
amount decimal.Decimal,
currency types.SupportedCurrency,
privateKey string,
receiverSlug string,
opts ...func(*CreateSingleSaleOfferOptions),
) error {
options := CreateSingleSaleOfferOptions{
Duration: 2 * 24 * time.Hour,
DelayBeforeStart: 5 * time.Second,
SettlementCurrencies: []types.SupportedCurrency{
types.SupportedCurrencyWEI,
types.SupportedCurrencyEUR,
},
}
if len(m.defaultSettlementCurrencies) > 0 {
options.SettlementCurrencies = m.defaultSettlementCurrencies
}
for _, opt := range opts {
opt(&options)
}
currencyShift := 2
if currency == types.SupportedCurrencyWEI {
currencyShift = 18
}
amount = amount.Shift(int32(currencyShift))
prepareOfferRes, err := m.newPrepareOfferMutation().Execute(ctx, PrepareOfferParams{
Input: prepareOfferInput{
Type: types.OfferTypeSingleSaleOffer,
SendAssetIds: []string{assetId},
ReceiveAssetIds: make([]string, 0),
ReceiveAmount: &AmountInput{
Amount: amount.String(),
Currency: currency,
},
ReceiverSlug: receiverSlug,
ClientMutationId: GetRandomId(),
SettlementCurrencies: options.SettlementCurrencies,
}})
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")
}
createSingleSaleOfferRes, err := m.newCreateSingleSaleOfferMutation().
Execute(ctx, CreateSingleSaleOfferParams{
Input: createSingleSaleOfferInput{
Approvals: approvals,
AssetId: assetId,
ClientMutationId: GetRandomId(),
DealId: GetRandomId(),
Duration: int(options.Duration.Seconds()),
ReceiveAmount: AmountInput{
Amount: amount.String(),
Currency: currency,
},
SettlementCurrencies: options.SettlementCurrencies,
StartDate: time.Now().
Add(options.DelayBeforeStart).
UTC().
Format(time.RFC3339),
}})
if err != nil {
return errors.Wrap(err, "creating single sale offer")
}
if len(createSingleSaleOfferRes.Errors) > 0 {
return errors.Wrap(
errors.New(createSingleSaleOfferRes.Errors[0].Message),
"creating single sale offer",
)
}
return nil
}