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 }