github.com/status-im/status-go@v1.1.0/services/stickers/transactions.go (about)

     1  package stickers
     2  
     3  import (
     4  	"context"
     5  	"math/big"
     6  	"strings"
     7  
     8  	"github.com/ethereum/go-ethereum/common/hexutil"
     9  
    10  	"github.com/ethereum/go-ethereum"
    11  	"github.com/ethereum/go-ethereum/accounts/abi"
    12  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    13  	"github.com/ethereum/go-ethereum/common"
    14  	"github.com/status-im/status-go/contracts/snt"
    15  	"github.com/status-im/status-go/contracts/stickers"
    16  	"github.com/status-im/status-go/eth-node/types"
    17  	"github.com/status-im/status-go/services/wallet/bigint"
    18  )
    19  
    20  func (api *API) BuyPrepareTxCallMsg(chainID uint64, from types.Address, packID *bigint.BigInt) (ethereum.CallMsg, error) {
    21  	callOpts := &bind.CallOpts{Context: api.ctx, Pending: false}
    22  
    23  	stickerType, err := api.contractMaker.NewStickerType(chainID)
    24  	if err != nil {
    25  		return ethereum.CallMsg{}, err
    26  	}
    27  
    28  	packInfo, err := stickerType.GetPackData(callOpts, packID.Int)
    29  	if err != nil {
    30  		return ethereum.CallMsg{}, err
    31  	}
    32  
    33  	stickerMarketABI, err := abi.JSON(strings.NewReader(stickers.StickerMarketABI))
    34  	if err != nil {
    35  		return ethereum.CallMsg{}, err
    36  	}
    37  
    38  	extraData, err := stickerMarketABI.Pack("buyToken", packID.Int, from, packInfo.Price)
    39  	if err != nil {
    40  		return ethereum.CallMsg{}, err
    41  	}
    42  
    43  	sntABI, err := abi.JSON(strings.NewReader(snt.SNTABI))
    44  	if err != nil {
    45  		return ethereum.CallMsg{}, err
    46  	}
    47  
    48  	stickerMarketAddress, err := stickers.StickerMarketContractAddress(chainID)
    49  	if err != nil {
    50  		return ethereum.CallMsg{}, err
    51  	}
    52  
    53  	data, err := sntABI.Pack("approveAndCall", stickerMarketAddress, packInfo.Price, extraData)
    54  	if err != nil {
    55  		return ethereum.CallMsg{}, err
    56  	}
    57  
    58  	sntAddress, err := snt.ContractAddress(chainID)
    59  	if err != nil {
    60  		return ethereum.CallMsg{}, err
    61  	}
    62  
    63  	return ethereum.CallMsg{
    64  		From:  common.Address(from),
    65  		To:    &sntAddress,
    66  		Value: big.NewInt(0),
    67  		Data:  data,
    68  	}, nil
    69  }
    70  
    71  func (api *API) BuyPrepareTx(ctx context.Context, chainID uint64, from types.Address, packID *bigint.BigInt) (interface{}, error) {
    72  	callMsg, err := api.BuyPrepareTxCallMsg(chainID, from, packID)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	return toCallArg(callMsg), nil
    78  }
    79  
    80  func (api *API) BuyEstimate(ctx context.Context, chainID uint64, from types.Address, packID *bigint.BigInt) (uint64, error) {
    81  	callMsg, err := api.BuyPrepareTxCallMsg(chainID, from, packID)
    82  	if err != nil {
    83  		return 0, err
    84  	}
    85  	ethClient, err := api.contractMaker.RPCClient.EthClient(chainID)
    86  	if err != nil {
    87  		return 0, err
    88  	}
    89  
    90  	return ethClient.EstimateGas(ctx, callMsg)
    91  }
    92  
    93  func (api *API) StickerMarketAddress(ctx context.Context, chainID uint64) (common.Address, error) {
    94  	return stickers.StickerMarketContractAddress(chainID)
    95  }
    96  
    97  func toCallArg(msg ethereum.CallMsg) interface{} {
    98  	arg := map[string]interface{}{
    99  		"from": msg.From,
   100  		"to":   msg.To,
   101  	}
   102  	if len(msg.Data) > 0 {
   103  		arg["data"] = hexutil.Bytes(msg.Data)
   104  	}
   105  	if msg.Value != nil {
   106  		arg["value"] = (*hexutil.Big)(msg.Value)
   107  	}
   108  	if msg.Gas != 0 {
   109  		arg["gas"] = hexutil.Uint64(msg.Gas)
   110  	}
   111  	if msg.GasPrice != nil {
   112  		arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
   113  	}
   114  	return arg
   115  }