2022-02-02 22:50:55 +00:00
|
|
|
package stickers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"math/big"
|
|
|
|
"strings"
|
|
|
|
|
2022-05-09 13:07:57 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
|
|
|
2022-02-02 22:50:55 +00:00
|
|
|
"github.com/ethereum/go-ethereum"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
|
"github.com/status-im/status-go/contracts/snt"
|
|
|
|
"github.com/status-im/status-go/contracts/stickers"
|
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
2023-06-21 14:09:55 +00:00
|
|
|
"github.com/status-im/status-go/services/rpcfilters"
|
2023-01-12 15:17:21 +00:00
|
|
|
"github.com/status-im/status-go/services/utils"
|
2022-02-13 23:43:08 +00:00
|
|
|
"github.com/status-im/status-go/services/wallet/bigint"
|
2022-02-02 22:50:55 +00:00
|
|
|
"github.com/status-im/status-go/transactions"
|
|
|
|
)
|
|
|
|
|
2022-02-13 23:43:08 +00:00
|
|
|
func (api *API) Buy(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, packID *bigint.BigInt, password string) (string, error) {
|
2022-02-02 22:50:55 +00:00
|
|
|
snt, err := api.contractMaker.NewSNT(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
stickerType, err := api.contractMaker.NewStickerType(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
callOpts := &bind.CallOpts{Context: api.ctx, Pending: false}
|
|
|
|
|
2022-02-13 23:43:08 +00:00
|
|
|
packInfo, err := stickerType.GetPackData(callOpts, packID.Int)
|
2022-02-02 22:50:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
stickerMarketABI, err := abi.JSON(strings.NewReader(stickers.StickerMarketABI))
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2022-02-14 23:25:56 +00:00
|
|
|
extraData, err := stickerMarketABI.Pack("buyToken", packID.Int, txArgs.From, packInfo.Price)
|
2022-02-02 22:50:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
stickerMarketAddress, err := stickers.StickerMarketContractAddress(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-01-12 15:17:21 +00:00
|
|
|
txOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.accountsManager, api.keyStoreDir, txArgs.From, password))
|
2022-02-02 22:50:55 +00:00
|
|
|
tx, err := snt.ApproveAndCall(
|
|
|
|
txOpts,
|
|
|
|
stickerMarketAddress,
|
|
|
|
packInfo.Price,
|
|
|
|
extraData,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2022-02-28 00:12:34 +00:00
|
|
|
err = api.AddPending(chainID, packID)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2022-02-02 22:50:55 +00:00
|
|
|
// TODO: track pending transaction (do this in ENS service too)
|
2023-06-21 14:09:55 +00:00
|
|
|
go api.rpcFiltersSrvc.TriggerTransactionSentToUpstreamEvent(&rpcfilters.PendingTxInfo{
|
|
|
|
Hash: tx.Hash(),
|
|
|
|
Type: string(transactions.BuyStickerPack),
|
|
|
|
From: common.Address(txArgs.From),
|
|
|
|
ChainID: chainID,
|
|
|
|
})
|
2022-02-02 22:50:55 +00:00
|
|
|
return tx.Hash().String(), nil
|
|
|
|
}
|
|
|
|
|
2022-05-09 13:07:57 +00:00
|
|
|
func (api *API) BuyPrepareTxCallMsg(chainID uint64, from types.Address, packID *bigint.BigInt) (ethereum.CallMsg, error) {
|
2022-02-02 22:50:55 +00:00
|
|
|
callOpts := &bind.CallOpts{Context: api.ctx, Pending: false}
|
|
|
|
|
|
|
|
stickerType, err := api.contractMaker.NewStickerType(chainID)
|
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
2022-02-14 23:25:56 +00:00
|
|
|
packInfo, err := stickerType.GetPackData(callOpts, packID.Int)
|
2022-02-02 22:50:55 +00:00
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stickerMarketABI, err := abi.JSON(strings.NewReader(stickers.StickerMarketABI))
|
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
2022-02-14 23:25:56 +00:00
|
|
|
extraData, err := stickerMarketABI.Pack("buyToken", packID.Int, from, packInfo.Price)
|
2022-02-02 22:50:55 +00:00
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sntABI, err := abi.JSON(strings.NewReader(snt.SNTABI))
|
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stickerMarketAddress, err := stickers.StickerMarketContractAddress(chainID)
|
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data, err := sntABI.Pack("approveAndCall", stickerMarketAddress, packInfo.Price, extraData)
|
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sntAddress, err := snt.ContractAddress(chainID)
|
|
|
|
if err != nil {
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{}, err
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
|
|
|
|
2022-05-09 13:07:57 +00:00
|
|
|
return ethereum.CallMsg{
|
2022-02-14 23:25:56 +00:00
|
|
|
From: common.Address(from),
|
2022-02-02 22:50:55 +00:00
|
|
|
To: &sntAddress,
|
|
|
|
Value: big.NewInt(0),
|
|
|
|
Data: data,
|
2022-05-09 13:07:57 +00:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) BuyPrepareTx(ctx context.Context, chainID uint64, from types.Address, packID *bigint.BigInt) (interface{}, error) {
|
|
|
|
callMsg, err := api.BuyPrepareTxCallMsg(chainID, from, packID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-02-14 23:25:56 +00:00
|
|
|
|
2022-05-09 13:07:57 +00:00
|
|
|
return toCallArg(callMsg), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) BuyEstimate(ctx context.Context, chainID uint64, from types.Address, packID *bigint.BigInt) (uint64, error) {
|
|
|
|
callMsg, err := api.BuyPrepareTxCallMsg(chainID, from, packID)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
ethClient, err := api.contractMaker.RPCClient.EthClient(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return ethClient.EstimateGas(ctx, callMsg)
|
2022-02-02 22:50:55 +00:00
|
|
|
}
|
2022-02-28 00:12:34 +00:00
|
|
|
|
|
|
|
func (api *API) StickerMarketAddress(ctx context.Context, chainID uint64) (common.Address, error) {
|
|
|
|
return stickers.StickerMarketContractAddress(chainID)
|
|
|
|
}
|
2022-05-09 13:07:57 +00:00
|
|
|
|
|
|
|
func toCallArg(msg ethereum.CallMsg) interface{} {
|
|
|
|
arg := map[string]interface{}{
|
|
|
|
"from": msg.From,
|
|
|
|
"to": msg.To,
|
|
|
|
}
|
|
|
|
if len(msg.Data) > 0 {
|
|
|
|
arg["data"] = hexutil.Bytes(msg.Data)
|
|
|
|
}
|
|
|
|
if msg.Value != nil {
|
|
|
|
arg["value"] = (*hexutil.Big)(msg.Value)
|
|
|
|
}
|
|
|
|
if msg.Gas != 0 {
|
|
|
|
arg["gas"] = hexutil.Uint64(msg.Gas)
|
|
|
|
}
|
|
|
|
if msg.GasPrice != nil {
|
|
|
|
arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
|
|
|
|
}
|
|
|
|
return arg
|
|
|
|
}
|