Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-maj committed Mar 13, 2023
2 parents 63211f2 + 9a8e25e commit 20e3683
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
119 changes: 119 additions & 0 deletions thirdweb/erc721_signature_minting.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package thirdweb
import (
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -366,6 +367,124 @@ func (signature *ERC721SignatureMinting) GenerateBatch(ctx context.Context, payl
return signedPayloads, nil
}

func (signature *ERC721SignatureMinting) GenerateBatchWithUris(ctx context.Context, payloadsToSign []*Signature721PayloadInputWithUri) ([]*SignedPayload721, error) {
// TODO: Verify roles and return error

chainId, err := signature.Helper.GetChainID(ctx)
if err != nil {
return nil, err
}

signedPayloads := []*SignedPayload721{}

for _, p := range payloadsToSign {

generatedId := uuid.New()
id := [32]byte{}
for i := 0; i < 16; i++ {
id[16+i] = generatedId[i]
}

provider := signature.Helper.GetProvider()
price, err := normalizePriceValue(ctx, provider, p.Price, p.CurrencyAddress)
if err != nil {
return nil, err
}

body, err := signature.storage.Get(ctx, p.MetadataUri)
if err != nil {
return nil, err
}

metadata := NFTMetadataInput{}
err = json.Unmarshal(body, &metadata)
if err != nil {
return nil, err
}

payload := &Signature721PayloadOutput{
To: p.To,
Price: price.String(),
CurrencyAddress: p.CurrencyAddress,
MintStartTime: p.MintStartTime,
MintEndTime: p.MintEndTime,
PrimarySaleRecipient: p.PrimarySaleRecipient,
RoyaltyRecipient: p.RoyaltyRecipient,
RoyaltyBps: p.RoyaltyBps,
Metadata: &metadata,
Uri: p.MetadataUri,
Uid: id,
}

mappedPayload, err := signature.generateMessage(ctx, payload)
if err != nil {
return nil, err
}

typedData := signerTypes.TypedData{
Types: signerTypes.Types{
"MintRequest": []signerTypes.Type{
{Name: "to", Type: "address"},
{Name: "royaltyRecipient", Type: "address"},
{Name: "royaltyBps", Type: "uint256"},
{Name: "primarySaleRecipient", Type: "address"},
{Name: "uri", Type: "string"},
{Name: "price", Type: "uint256"},
{Name: "currency", Type: "address"},
{Name: "validityStartTimestamp", Type: "uint128"},
{Name: "validityEndTimestamp", Type: "uint128"},
{Name: "uid", Type: "bytes32"},
},
"EIP712Domain": []signerTypes.Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
},
},
PrimaryType: "MintRequest",
Domain: signerTypes.TypedDataDomain{
Name: "TokenERC721",
Version: "1",
ChainId: math.NewHexOrDecimal256(chainId.Int64()),
VerifyingContract: signature.Helper.getAddress().String(),
},
Message: mappedPayload,
}

domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map())
if err != nil {
return nil, err
}

typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message)
if err != nil {
return nil, err
}

rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash)))
sigHash := crypto.Keccak256(rawData)

privateKey := signature.Helper.GetPrivateKey()
signatureHash, err := crypto.Sign(sigHash, privateKey)
if err != nil {
return nil, err
}

// We need this to correct v = 0,1 to v = 27,28 - or else all will break
if signatureHash[64] == 0 || signatureHash[64] == 1 {
signatureHash[64] += 27
}

signedPayloads = append(signedPayloads, &SignedPayload721{
Payload: payload,
Signature: "0x" + hex.EncodeToString(signatureHash),
})
}

return signedPayloads, nil
}

func (signature *ERC721SignatureMinting) generateMessage(ctx context.Context, mintRequest *Signature721PayloadOutput) (signerTypes.TypedDataMessage, error) {
message := signerTypes.TypedDataMessage{
"to": mintRequest.To,
Expand Down
13 changes: 13 additions & 0 deletions thirdweb/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,19 @@ type Signature721PayloadInput struct {
RoyaltyBps int
}

type Signature721PayloadInputWithUri struct {
To string
Price float64
CurrencyAddress string
MintStartTime int
MintEndTime int
PrimarySaleRecipient string
MetadataUri string
RoyaltyRecipient string
RoyaltyBps int
}


type Signature721PayloadOutput struct {
To string `json:"to"`
Price string `json:"price"`
Expand Down

0 comments on commit 20e3683

Please sign in to comment.