feat_: add l1 transaction fee to community token contracts operations
Move estimation funtions to a estimations.go Compute gas, suggested fees and l1 fee in one status-go call Issue #14166
This commit is contained in:
parent
ae08ba6ad1
commit
c3ab8bd658
|
@ -487,7 +487,7 @@ func (b *StatusNode) pendingTrackerService(walletFeed *event.Feed) *transactions
|
||||||
|
|
||||||
func (b *StatusNode) CommunityTokensService() *communitytokens.Service {
|
func (b *StatusNode) CommunityTokensService() *communitytokens.Service {
|
||||||
if b.communityTokensSrvc == nil {
|
if b.communityTokensSrvc == nil {
|
||||||
b.communityTokensSrvc = communitytokens.NewService(b.rpcClient, b.gethAccountManager, b.pendingTracker, b.config, b.appDB, &b.walletFeed)
|
b.communityTokensSrvc = communitytokens.NewService(b.rpcClient, b.gethAccountManager, b.pendingTracker, b.config, b.appDB, &b.walletFeed, b.transactor)
|
||||||
}
|
}
|
||||||
return b.communityTokensSrvc
|
return b.communityTokensSrvc
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,19 +4,16 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"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/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/status-im/status-go/contracts/community-tokens/assets"
|
"github.com/status-im/status-go/contracts/community-tokens/assets"
|
||||||
"github.com/status-im/status-go/contracts/community-tokens/collectibles"
|
"github.com/status-im/status-go/contracts/community-tokens/collectibles"
|
||||||
communitytokendeployer "github.com/status-im/status-go/contracts/community-tokens/deployer"
|
communitytokendeployer "github.com/status-im/status-go/contracts/community-tokens/deployer"
|
||||||
"github.com/status-im/status-go/contracts/community-tokens/mastertoken"
|
|
||||||
"github.com/status-im/status-go/contracts/community-tokens/ownertoken"
|
"github.com/status-im/status-go/contracts/community-tokens/ownertoken"
|
||||||
communityownertokenregistry "github.com/status-im/status-go/contracts/community-tokens/registry"
|
communityownertokenregistry "github.com/status-im/status-go/contracts/community-tokens/registry"
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
@ -321,147 +318,35 @@ func (api *API) DeployAssets(ctx context.Context, chainID uint64, deploymentPara
|
||||||
CommunityToken: savedCommunityToken}, nil
|
CommunityToken: savedCommunityToken}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns gas units + 10%
|
func (api *API) DeployCollectiblesEstimate(ctx context.Context, chainID uint64, fromAddress string) (*CommunityTokenFees, error) {
|
||||||
func (api *API) DeployCollectiblesEstimate(ctx context.Context, chainID uint64, fromAddress string) (uint64, error) {
|
return api.s.deployCollectiblesEstimate(ctx, chainID, fromAddress)
|
||||||
ethClient, err := api.s.manager.rpcClient.EthClient(chainID)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
return 0, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
collectiblesABI, err := abi.JSON(strings.NewReader(collectibles.CollectiblesABI))
|
func (api *API) DeployAssetsEstimate(ctx context.Context, chainID uint64, fromAddress string) (*CommunityTokenFees, error) {
|
||||||
if err != nil {
|
return api.s.deployAssetsEstimate(ctx, chainID, fromAddress)
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// use random parameters, they will not have impact on deployment results
|
|
||||||
data, err := collectiblesABI.Pack("" /*constructor name is empty*/, "name", "SYMBOL", big.NewInt(20), true, false, "tokenUri",
|
|
||||||
common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"), common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
callMsg := ethereum.CallMsg{
|
|
||||||
From: common.HexToAddress(fromAddress),
|
|
||||||
To: nil,
|
|
||||||
Value: big.NewInt(0),
|
|
||||||
Data: append(common.FromHex(collectibles.CollectiblesBin), data...),
|
|
||||||
}
|
|
||||||
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
finalEstimation := estimate + uint64(float32(estimate)*0.1)
|
|
||||||
log.Debug("Collectibles deployment gas estimation: ", finalEstimation)
|
|
||||||
return finalEstimation, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns gas units + 10%
|
|
||||||
func (api *API) DeployAssetsEstimate(ctx context.Context, chainID uint64, fromAddress string) (uint64, error) {
|
|
||||||
ethClient, err := api.s.manager.rpcClient.EthClient(chainID)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
assetsABI, err := abi.JSON(strings.NewReader(assets.AssetsABI))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// use random parameters, they will not have impact on deployment results
|
|
||||||
data, err := assetsABI.Pack("" /*constructor name is empty*/, "name", "SYMBOL", uint8(18), big.NewInt(20), "tokenUri",
|
|
||||||
common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"), common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
callMsg := ethereum.CallMsg{
|
|
||||||
From: common.HexToAddress(fromAddress),
|
|
||||||
To: nil,
|
|
||||||
Value: big.NewInt(0),
|
|
||||||
Data: append(common.FromHex(assets.AssetsBin), data...),
|
|
||||||
}
|
|
||||||
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
finalEstimation := estimate + uint64(float32(estimate)*0.1)
|
|
||||||
log.Debug("Assets deployment gas estimation: ", finalEstimation)
|
|
||||||
return finalEstimation, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) DeployOwnerTokenEstimate(ctx context.Context, chainID uint64, fromAddress string,
|
func (api *API) DeployOwnerTokenEstimate(ctx context.Context, chainID uint64, fromAddress string,
|
||||||
ownerTokenParameters DeploymentParameters, masterTokenParameters DeploymentParameters,
|
ownerTokenParameters DeploymentParameters, masterTokenParameters DeploymentParameters,
|
||||||
communityID string, signerPubKey string) (uint64, error) {
|
communityID string, signerPubKey string) (*CommunityTokenFees, error) {
|
||||||
ethClient, err := api.s.manager.rpcClient.EthClient(chainID)
|
return api.s.deployOwnerTokenEstimate(ctx, chainID, fromAddress, ownerTokenParameters, masterTokenParameters, communityID, signerPubKey)
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
return 0, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deployerAddress, err := communitytokendeployer.ContractAddress(chainID)
|
func (api *API) EstimateMintTokens(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (*CommunityTokenFees, error) {
|
||||||
if err != nil {
|
return api.s.mintTokensEstimate(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
||||||
return 0, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deployerABI, err := abi.JSON(strings.NewReader(communitytokendeployer.CommunityTokenDeployerABI))
|
// This is only ERC721 function
|
||||||
if err != nil {
|
func (api *API) EstimateRemoteBurn(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, tokenIds []*bigint.BigInt) (*CommunityTokenFees, error) {
|
||||||
return 0, err
|
return api.s.remoteBurnEstimate(ctx, chainID, contractAddress, fromAddress, tokenIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerTokenConfig := communitytokendeployer.CommunityTokenDeployerTokenConfig{
|
func (api *API) EstimateBurn(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, burnAmount *bigint.BigInt) (*CommunityTokenFees, error) {
|
||||||
Name: ownerTokenParameters.Name,
|
return api.s.burnEstimate(ctx, chainID, contractAddress, fromAddress, burnAmount)
|
||||||
Symbol: ownerTokenParameters.Symbol,
|
|
||||||
BaseURI: ownerTokenParameters.TokenURI,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
masterTokenConfig := communitytokendeployer.CommunityTokenDeployerTokenConfig{
|
func (api *API) EstimateSetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, newSignerPubKey string) (*CommunityTokenFees, error) {
|
||||||
Name: masterTokenParameters.Name,
|
return api.s.setSignerPubKeyEstimate(ctx, chainID, contractAddress, fromAddress, newSignerPubKey)
|
||||||
Symbol: masterTokenParameters.Symbol,
|
|
||||||
BaseURI: masterTokenParameters.TokenURI,
|
|
||||||
}
|
|
||||||
|
|
||||||
signature, err := api.s.Messenger.CreateCommunityTokenDeploymentSignature(ctx, chainID, fromAddress, communityID)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
communitySignature, err := prepareDeploymentSignatureStruct(types.HexBytes(signature).String(), communityID, common.HexToAddress(fromAddress))
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := deployerABI.Pack("deploy", ownerTokenConfig, masterTokenConfig, communitySignature, common.FromHex(signerPubKey))
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
toAddr := deployerAddress
|
|
||||||
fromAddr := common.HexToAddress(fromAddress)
|
|
||||||
|
|
||||||
callMsg := ethereum.CallMsg{
|
|
||||||
From: fromAddr,
|
|
||||||
To: &toAddr,
|
|
||||||
Value: big.NewInt(0),
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return estimate + uint64(float32(estimate)*0.1), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) NewMasterTokenInstance(chainID uint64, contractAddress string) (*mastertoken.MasterToken, error) {
|
|
||||||
backend, err := api.s.manager.rpcClient.EthClient(chainID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return mastertoken.NewMasterToken(common.HexToAddress(contractAddress), backend)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) NewOwnerTokenInstance(chainID uint64, contractAddress string) (*ownertoken.OwnerToken, error) {
|
func (api *API) NewOwnerTokenInstance(chainID uint64, contractAddress string) (*ownertoken.OwnerToken, error) {
|
||||||
|
@ -484,37 +369,17 @@ func (api *API) NewAssetsInstance(chainID uint64, contractAddress string) (*asse
|
||||||
return api.s.manager.NewAssetsInstance(chainID, contractAddress)
|
return api.s.manager.NewAssetsInstance(chainID, contractAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we want to mint 2 tokens to addresses ["a", "b"] we need to mint
|
|
||||||
// twice to every address - we need to send to smart contract table ["a", "a", "b", "b"]
|
|
||||||
func (api *API) multiplyWalletAddresses(amount *bigint.BigInt, contractAddresses []string) []string {
|
|
||||||
var totalAddresses []string
|
|
||||||
for i := big.NewInt(1); i.Cmp(amount.Int) <= 0; {
|
|
||||||
totalAddresses = append(totalAddresses, contractAddresses...)
|
|
||||||
i.Add(i, big.NewInt(1))
|
|
||||||
}
|
|
||||||
return totalAddresses
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) PrepareMintCollectiblesData(walletAddresses []string, amount *bigint.BigInt) []common.Address {
|
|
||||||
totalAddresses := api.multiplyWalletAddresses(amount, walletAddresses)
|
|
||||||
var usersAddresses = []common.Address{}
|
|
||||||
for _, k := range totalAddresses {
|
|
||||||
usersAddresses = append(usersAddresses, common.HexToAddress(k))
|
|
||||||
}
|
|
||||||
return usersAddresses
|
|
||||||
}
|
|
||||||
|
|
||||||
// Universal minting function for every type of token.
|
// Universal minting function for every type of token.
|
||||||
func (api *API) MintTokens(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, walletAddresses []string, amount *bigint.BigInt) (string, error) {
|
func (api *API) MintTokens(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, walletAddresses []string, amount *bigint.BigInt) (string, error) {
|
||||||
|
|
||||||
err := api.ValidateWalletsAndAmounts(walletAddresses, amount)
|
err := api.s.ValidateWalletsAndAmounts(walletAddresses, amount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
||||||
|
|
||||||
contractInst, err := NewTokenInstance(api, chainID, contractAddress)
|
contractInst, err := NewTokenInstance(api.s, chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -541,51 +406,6 @@ func (api *API) MintTokens(ctx context.Context, chainID uint64, contractAddress
|
||||||
return tx.Hash().Hex(), nil
|
return tx.Hash().Hex(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) EstimateMintTokens(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (uint64, error) {
|
|
||||||
tokenType, err := api.s.db.GetTokenType(chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch tokenType {
|
|
||||||
case protobuf.CommunityTokenType_ERC721:
|
|
||||||
return api.EstimateMintCollectibles(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
|
||||||
case protobuf.CommunityTokenType_ERC20:
|
|
||||||
return api.EstimateMintAssets(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
|
||||||
default:
|
|
||||||
return 0, fmt.Errorf("unknown token type: %v", tokenType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) EstimateMintCollectibles(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (uint64, error) {
|
|
||||||
err := api.ValidateWalletsAndAmounts(walletAddresses, amount)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
usersAddresses := api.PrepareMintCollectiblesData(walletAddresses, amount)
|
|
||||||
return api.estimateMethod(ctx, chainID, contractAddress, fromAddress, "mintTo", usersAddresses)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) PrepareMintAssetsData(walletAddresses []string, amount *bigint.BigInt) ([]common.Address, []*big.Int) {
|
|
||||||
var usersAddresses = []common.Address{}
|
|
||||||
var amountsList = []*big.Int{}
|
|
||||||
for _, k := range walletAddresses {
|
|
||||||
usersAddresses = append(usersAddresses, common.HexToAddress(k))
|
|
||||||
amountsList = append(amountsList, amount.Int)
|
|
||||||
}
|
|
||||||
return usersAddresses, amountsList
|
|
||||||
}
|
|
||||||
|
|
||||||
// Estimate MintAssets cost.
|
|
||||||
func (api *API) EstimateMintAssets(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (uint64, error) {
|
|
||||||
err := api.ValidateWalletsAndAmounts(walletAddresses, amount)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
usersAddresses, amountsList := api.PrepareMintAssetsData(walletAddresses, amount)
|
|
||||||
return api.estimateMethod(ctx, chainID, contractAddress, fromAddress, "mintTo", usersAddresses, amountsList)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is only ERC721 function
|
// This is only ERC721 function
|
||||||
func (api *API) RemoteDestructedAmount(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
func (api *API) RemoteDestructedAmount(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
||||||
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
||||||
|
@ -614,7 +434,7 @@ func (api *API) RemoteDestructedAmount(ctx context.Context, chainID uint64, cont
|
||||||
|
|
||||||
// This is only ERC721 function
|
// This is only ERC721 function
|
||||||
func (api *API) RemoteBurn(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, tokenIds []*bigint.BigInt, additionalData string) (string, error) {
|
func (api *API) RemoteBurn(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, tokenIds []*bigint.BigInt, additionalData string) (string, error) {
|
||||||
err := api.validateTokens(tokenIds)
|
err := api.s.validateTokens(tokenIds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -626,7 +446,7 @@ func (api *API) RemoteBurn(ctx context.Context, chainID uint64, contractAddress
|
||||||
tempTokenIds = append(tempTokenIds, v.Int)
|
tempTokenIds = append(tempTokenIds, v.Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
contractInst, err := NewTokenInstance(api, chainID, contractAddress)
|
contractInst, err := NewTokenInstance(api.s, chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -653,21 +473,6 @@ func (api *API) RemoteBurn(ctx context.Context, chainID uint64, contractAddress
|
||||||
return tx.Hash().Hex(), nil
|
return tx.Hash().Hex(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only ERC721 function
|
|
||||||
func (api *API) EstimateRemoteBurn(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, tokenIds []*bigint.BigInt) (uint64, error) {
|
|
||||||
err := api.validateTokens(tokenIds)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tempTokenIds []*big.Int
|
|
||||||
for _, v := range tokenIds {
|
|
||||||
tempTokenIds = append(tempTokenIds, v.Int)
|
|
||||||
}
|
|
||||||
|
|
||||||
return api.estimateMethod(ctx, chainID, contractAddress, fromAddress, "remoteBurn", tempTokenIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) GetCollectiblesContractInstance(chainID uint64, contractAddress string) (*collectibles.Collectibles, error) {
|
func (api *API) GetCollectiblesContractInstance(chainID uint64, contractAddress string) (*collectibles.Collectibles, error) {
|
||||||
return api.s.manager.GetCollectiblesContractInstance(chainID, contractAddress)
|
return api.s.manager.GetCollectiblesContractInstance(chainID, contractAddress)
|
||||||
}
|
}
|
||||||
|
@ -677,84 +482,23 @@ func (api *API) GetAssetContractInstance(chainID uint64, contractAddress string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) RemainingSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
func (api *API) RemainingSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
||||||
tokenType, err := api.s.db.GetTokenType(chainID, contractAddress)
|
return api.s.remainingSupply(ctx, chainID, contractAddress)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch tokenType {
|
|
||||||
case protobuf.CommunityTokenType_ERC721:
|
|
||||||
return api.remainingCollectiblesSupply(ctx, chainID, contractAddress)
|
|
||||||
case protobuf.CommunityTokenType_ERC20:
|
|
||||||
return api.remainingAssetsSupply(ctx, chainID, contractAddress)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown token type: %v", tokenType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemainingSupply = MaxSupply - MintedCount
|
|
||||||
func (api *API) remainingCollectiblesSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
|
||||||
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
|
||||||
contractInst, err := api.NewCollectiblesInstance(chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
maxSupply, err := contractInst.MaxSupply(callOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mintedCount, err := contractInst.MintedCount(callOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var res = new(big.Int)
|
|
||||||
res.Sub(maxSupply, mintedCount)
|
|
||||||
return &bigint.BigInt{Int: res}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemainingSupply = MaxSupply - TotalSupply
|
|
||||||
func (api *API) remainingAssetsSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
|
||||||
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
|
||||||
contractInst, err := api.NewAssetsInstance(chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
maxSupply, err := contractInst.MaxSupply(callOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
totalSupply, err := contractInst.TotalSupply(callOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var res = new(big.Int)
|
|
||||||
res.Sub(maxSupply, totalSupply)
|
|
||||||
return &bigint.BigInt{Int: res}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) prepareNewMaxSupply(ctx context.Context, chainID uint64, contractAddress string, burnAmount *bigint.BigInt) (*big.Int, error) {
|
|
||||||
maxSupply, err := api.s.maxSupply(ctx, chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var newMaxSupply = new(big.Int)
|
|
||||||
newMaxSupply.Sub(maxSupply, burnAmount.Int)
|
|
||||||
return newMaxSupply, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) Burn(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, burnAmount *bigint.BigInt) (string, error) {
|
func (api *API) Burn(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, burnAmount *bigint.BigInt) (string, error) {
|
||||||
err := api.validateBurnAmount(ctx, burnAmount, chainID, contractAddress)
|
err := api.s.validateBurnAmount(ctx, burnAmount, chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
||||||
|
|
||||||
newMaxSupply, err := api.prepareNewMaxSupply(ctx, chainID, contractAddress, burnAmount)
|
newMaxSupply, err := api.s.prepareNewMaxSupply(ctx, chainID, contractAddress, burnAmount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
contractInst, err := NewTokenInstance(api, chainID, contractAddress)
|
contractInst, err := NewTokenInstance(api.s, chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -781,88 +525,6 @@ func (api *API) Burn(ctx context.Context, chainID uint64, contractAddress string
|
||||||
return tx.Hash().Hex(), nil
|
return tx.Hash().Hex(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) EstimateBurn(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, burnAmount *bigint.BigInt) (uint64, error) {
|
|
||||||
err := api.validateBurnAmount(ctx, burnAmount, chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
newMaxSupply, err := api.prepareNewMaxSupply(ctx, chainID, contractAddress, burnAmount)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return api.estimateMethod(ctx, chainID, contractAddress, fromAddress, "setMaxSupply", newMaxSupply)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) ValidateWalletsAndAmounts(walletAddresses []string, amount *bigint.BigInt) error {
|
|
||||||
if len(walletAddresses) == 0 {
|
|
||||||
return errors.New("wallet addresses list is empty")
|
|
||||||
}
|
|
||||||
if amount.Cmp(big.NewInt(0)) <= 0 {
|
|
||||||
return errors.New("amount is <= 0")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) validateTokens(tokenIds []*bigint.BigInt) error {
|
|
||||||
if len(tokenIds) == 0 {
|
|
||||||
return errors.New("token list is empty")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) validateBurnAmount(ctx context.Context, burnAmount *bigint.BigInt, chainID uint64, contractAddress string) error {
|
|
||||||
if burnAmount.Cmp(big.NewInt(0)) <= 0 {
|
|
||||||
return errors.New("burnAmount is less than 0")
|
|
||||||
}
|
|
||||||
remainingSupply, err := api.RemainingSupply(ctx, chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if burnAmount.Cmp(remainingSupply.Int) > 1 {
|
|
||||||
return errors.New("burnAmount is bigger than remaining amount")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) estimateMethodForTokenInstance(ctx context.Context, contractInstance TokenInstance, chainID uint64, contractAddress string, fromAddress string, methodName string, args ...interface{}) (uint64, error) {
|
|
||||||
ethClient, err := api.s.manager.rpcClient.EthClient(chainID)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := contractInstance.PackMethod(ctx, methodName, args...)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
toAddr := common.HexToAddress(contractAddress)
|
|
||||||
fromAddr := common.HexToAddress(fromAddress)
|
|
||||||
|
|
||||||
callMsg := ethereum.CallMsg{
|
|
||||||
From: fromAddr,
|
|
||||||
To: &toAddr,
|
|
||||||
Value: big.NewInt(0),
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return estimate + uint64(float32(estimate)*0.1), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) estimateMethod(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, methodName string, args ...interface{}) (uint64, error) {
|
|
||||||
contractInst, err := NewTokenInstance(api, chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return api.estimateMethodForTokenInstance(ctx, contractInst, chainID, contractAddress, fromAddress, methodName, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets signer public key from smart contract with a given chainId and address
|
// Gets signer public key from smart contract with a given chainId and address
|
||||||
func (api *API) GetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
func (api *API) GetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
||||||
return api.s.GetSignerPubKey(ctx, chainID, contractAddress)
|
return api.s.GetSignerPubKey(ctx, chainID, contractAddress)
|
||||||
|
@ -882,20 +544,6 @@ func (api *API) SetSignerPubKey(ctx context.Context, chainID uint64, contractAdd
|
||||||
return api.s.SetSignerPubKey(ctx, chainID, contractAddress, txArgs, password, newSignerPubKey)
|
return api.s.SetSignerPubKey(ctx, chainID, contractAddress, txArgs, password, newSignerPubKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) EstimateSetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, newSignerPubKey string) (uint64, error) {
|
|
||||||
if len(newSignerPubKey) <= 0 {
|
|
||||||
return 0, fmt.Errorf("signerPubKey is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
contractInst, err := api.NewOwnerTokenInstance(chainID, contractAddress)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
ownerTokenInstance := &OwnerTokenInstance{instance: contractInst}
|
|
||||||
|
|
||||||
return api.estimateMethodForTokenInstance(ctx, ownerTokenInstance, chainID, contractAddress, fromAddress, "setSignerPublicKey", common.FromHex(newSignerPubKey))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) OwnerTokenOwnerAddress(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
func (api *API) OwnerTokenOwnerAddress(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
||||||
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
||||||
contractInst, err := api.NewOwnerTokenInstance(chainID, contractAddress)
|
contractInst, err := api.NewOwnerTokenInstance(chainID, contractAddress)
|
||||||
|
|
|
@ -0,0 +1,435 @@
|
||||||
|
package communitytokens
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum"
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/status-im/status-go/contracts/community-tokens/assets"
|
||||||
|
"github.com/status-im/status-go/contracts/community-tokens/collectibles"
|
||||||
|
communitytokendeployer "github.com/status-im/status-go/contracts/community-tokens/deployer"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
|
"github.com/status-im/status-go/services/wallet"
|
||||||
|
"github.com/status-im/status-go/services/wallet/bigint"
|
||||||
|
"github.com/status-im/status-go/transactions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommunityTokenFees struct {
|
||||||
|
GasUnits uint64 `json:"gasUnits"`
|
||||||
|
SuggestedFees *wallet.SuggestedFees `json:"suggestedFees"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func weiToGwei(val *big.Int) *big.Float {
|
||||||
|
result := new(big.Float)
|
||||||
|
result.SetInt(val)
|
||||||
|
|
||||||
|
unit := new(big.Int)
|
||||||
|
unit.SetInt64(params.GWei)
|
||||||
|
|
||||||
|
return result.Quo(result, new(big.Float).SetInt(unit))
|
||||||
|
}
|
||||||
|
|
||||||
|
func gweiToWei(val *big.Float) *big.Int {
|
||||||
|
res, _ := new(big.Float).Mul(val, big.NewFloat(1000000000)).Int(nil)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) deployOwnerTokenEstimate(ctx context.Context, chainID uint64, fromAddress string,
|
||||||
|
ownerTokenParameters DeploymentParameters, masterTokenParameters DeploymentParameters,
|
||||||
|
communityID string, signerPubKey string) (*CommunityTokenFees, error) {
|
||||||
|
|
||||||
|
gasUnits, err := s.deployOwnerTokenGasUnits(ctx, chainID, fromAddress, ownerTokenParameters, masterTokenParameters,
|
||||||
|
communityID, signerPubKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deployerAddress, err := communitytokendeployer.ContractAddress(chainID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), &deployerAddress, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) deployCollectiblesEstimate(ctx context.Context, chainID uint64, fromAddress string) (*CommunityTokenFees, error) {
|
||||||
|
gasUnits, err := s.deployCollectiblesGasUnits(ctx, chainID, fromAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), nil, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) deployAssetsEstimate(ctx context.Context, chainID uint64, fromAddress string) (*CommunityTokenFees, error) {
|
||||||
|
gasUnits, err := s.deployAssetsGasUnits(ctx, chainID, fromAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), nil, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) mintTokensEstimate(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (*CommunityTokenFees, error) {
|
||||||
|
gasUnits, err := s.mintTokensGasUnits(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
toAddress := common.HexToAddress(contractAddress)
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), &toAddress, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) remoteBurnEstimate(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, tokenIds []*bigint.BigInt) (*CommunityTokenFees, error) {
|
||||||
|
gasUnits, err := s.remoteBurnGasUnits(ctx, chainID, contractAddress, fromAddress, tokenIds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
toAddress := common.HexToAddress(contractAddress)
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), &toAddress, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) burnEstimate(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, burnAmount *bigint.BigInt) (*CommunityTokenFees, error) {
|
||||||
|
gasUnits, err := s.burnGasUnits(ctx, chainID, contractAddress, fromAddress, burnAmount)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
toAddress := common.HexToAddress(contractAddress)
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), &toAddress, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) setSignerPubKeyEstimate(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, newSignerPubKey string) (*CommunityTokenFees, error) {
|
||||||
|
gasUnits, err := s.setSignerPubKeyGasUnits(ctx, chainID, contractAddress, fromAddress, newSignerPubKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
toAddress := common.HexToAddress(contractAddress)
|
||||||
|
return s.prepareCommunityTokenFees(ctx, common.HexToAddress(fromAddress), &toAddress, gasUnits, chainID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) setSignerPubKeyGasUnits(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, newSignerPubKey string) (uint64, error) {
|
||||||
|
if len(newSignerPubKey) <= 0 {
|
||||||
|
return 0, fmt.Errorf("signerPubKey is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
contractInst, err := s.NewOwnerTokenInstance(chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
ownerTokenInstance := &OwnerTokenInstance{instance: contractInst}
|
||||||
|
|
||||||
|
return s.estimateMethodForTokenInstance(ctx, ownerTokenInstance, chainID, contractAddress, fromAddress, "setSignerPublicKey", common.FromHex(newSignerPubKey))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) burnGasUnits(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, burnAmount *bigint.BigInt) (uint64, error) {
|
||||||
|
err := s.validateBurnAmount(ctx, burnAmount, chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newMaxSupply, err := s.prepareNewMaxSupply(ctx, chainID, contractAddress, burnAmount)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.estimateMethod(ctx, chainID, contractAddress, fromAddress, "setMaxSupply", newMaxSupply)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) remoteBurnGasUnits(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, tokenIds []*bigint.BigInt) (uint64, error) {
|
||||||
|
err := s.validateTokens(tokenIds)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempTokenIds []*big.Int
|
||||||
|
for _, v := range tokenIds {
|
||||||
|
tempTokenIds = append(tempTokenIds, v.Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.estimateMethod(ctx, chainID, contractAddress, fromAddress, "remoteBurn", tempTokenIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) deployOwnerTokenGasUnits(ctx context.Context, chainID uint64, fromAddress string,
|
||||||
|
ownerTokenParameters DeploymentParameters, masterTokenParameters DeploymentParameters,
|
||||||
|
communityID string, signerPubKey string) (uint64, error) {
|
||||||
|
ethClient, err := s.manager.rpcClient.EthClient(chainID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deployerAddress, err := communitytokendeployer.ContractAddress(chainID)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deployerABI, err := abi.JSON(strings.NewReader(communitytokendeployer.CommunityTokenDeployerABI))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerTokenConfig := communitytokendeployer.CommunityTokenDeployerTokenConfig{
|
||||||
|
Name: ownerTokenParameters.Name,
|
||||||
|
Symbol: ownerTokenParameters.Symbol,
|
||||||
|
BaseURI: ownerTokenParameters.TokenURI,
|
||||||
|
}
|
||||||
|
|
||||||
|
masterTokenConfig := communitytokendeployer.CommunityTokenDeployerTokenConfig{
|
||||||
|
Name: masterTokenParameters.Name,
|
||||||
|
Symbol: masterTokenParameters.Symbol,
|
||||||
|
BaseURI: masterTokenParameters.TokenURI,
|
||||||
|
}
|
||||||
|
|
||||||
|
signature, err := s.Messenger.CreateCommunityTokenDeploymentSignature(ctx, chainID, fromAddress, communityID)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
communitySignature, err := prepareDeploymentSignatureStruct(types.HexBytes(signature).String(), communityID, common.HexToAddress(fromAddress))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := deployerABI.Pack("deploy", ownerTokenConfig, masterTokenConfig, communitySignature, common.FromHex(signerPubKey))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
toAddr := deployerAddress
|
||||||
|
fromAddr := common.HexToAddress(fromAddress)
|
||||||
|
|
||||||
|
callMsg := ethereum.CallMsg{
|
||||||
|
From: fromAddr,
|
||||||
|
To: &toAddr,
|
||||||
|
Value: big.NewInt(0),
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
|
||||||
|
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
finalEstimation := estimate + uint64(float32(estimate)*0.1)
|
||||||
|
log.Debug("Owner token deployment gas estimation: ", finalEstimation)
|
||||||
|
return finalEstimation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) deployCollectiblesGasUnits(ctx context.Context, chainID uint64, fromAddress string) (uint64, error) {
|
||||||
|
ethClient, err := s.manager.rpcClient.EthClient(chainID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
collectiblesABI, err := abi.JSON(strings.NewReader(collectibles.CollectiblesABI))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// use random parameters, they will not have impact on deployment results
|
||||||
|
data, err := collectiblesABI.Pack("" /*constructor name is empty*/, "name", "SYMBOL", big.NewInt(20), true, false, "tokenUri",
|
||||||
|
common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"), common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
callMsg := ethereum.CallMsg{
|
||||||
|
From: common.HexToAddress(fromAddress),
|
||||||
|
To: nil,
|
||||||
|
Value: big.NewInt(0),
|
||||||
|
Data: append(common.FromHex(collectibles.CollectiblesBin), data...),
|
||||||
|
}
|
||||||
|
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
finalEstimation := estimate + uint64(float32(estimate)*0.1)
|
||||||
|
log.Debug("Collectibles deployment gas estimation: ", finalEstimation)
|
||||||
|
return finalEstimation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) deployAssetsGasUnits(ctx context.Context, chainID uint64, fromAddress string) (uint64, error) {
|
||||||
|
ethClient, err := s.manager.rpcClient.EthClient(chainID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
assetsABI, err := abi.JSON(strings.NewReader(assets.AssetsABI))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// use random parameters, they will not have impact on deployment results
|
||||||
|
data, err := assetsABI.Pack("" /*constructor name is empty*/, "name", "SYMBOL", uint8(18), big.NewInt(20), "tokenUri",
|
||||||
|
common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"), common.HexToAddress("0x77b48394c650520012795a1a25696d7eb542d110"))
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
callMsg := ethereum.CallMsg{
|
||||||
|
From: common.HexToAddress(fromAddress),
|
||||||
|
To: nil,
|
||||||
|
Value: big.NewInt(0),
|
||||||
|
Data: append(common.FromHex(assets.AssetsBin), data...),
|
||||||
|
}
|
||||||
|
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
finalEstimation := estimate + uint64(float32(estimate)*0.1)
|
||||||
|
log.Debug("Assets deployment gas estimation: ", finalEstimation)
|
||||||
|
return finalEstimation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we want to mint 2 tokens to addresses ["a", "b"] we need to mint
|
||||||
|
// twice to every address - we need to send to smart contract table ["a", "a", "b", "b"]
|
||||||
|
func multiplyWalletAddresses(amount *bigint.BigInt, contractAddresses []string) []string {
|
||||||
|
var totalAddresses []string
|
||||||
|
for i := big.NewInt(1); i.Cmp(amount.Int) <= 0; {
|
||||||
|
totalAddresses = append(totalAddresses, contractAddresses...)
|
||||||
|
i.Add(i, big.NewInt(1))
|
||||||
|
}
|
||||||
|
return totalAddresses
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareMintCollectiblesData(walletAddresses []string, amount *bigint.BigInt) []common.Address {
|
||||||
|
totalAddresses := multiplyWalletAddresses(amount, walletAddresses)
|
||||||
|
var usersAddresses = []common.Address{}
|
||||||
|
for _, k := range totalAddresses {
|
||||||
|
usersAddresses = append(usersAddresses, common.HexToAddress(k))
|
||||||
|
}
|
||||||
|
return usersAddresses
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareMintAssetsData(walletAddresses []string, amount *bigint.BigInt) ([]common.Address, []*big.Int) {
|
||||||
|
var usersAddresses = []common.Address{}
|
||||||
|
var amountsList = []*big.Int{}
|
||||||
|
for _, k := range walletAddresses {
|
||||||
|
usersAddresses = append(usersAddresses, common.HexToAddress(k))
|
||||||
|
amountsList = append(amountsList, amount.Int)
|
||||||
|
}
|
||||||
|
return usersAddresses, amountsList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) mintCollectiblesGasUnits(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (uint64, error) {
|
||||||
|
err := s.ValidateWalletsAndAmounts(walletAddresses, amount)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
usersAddresses := prepareMintCollectiblesData(walletAddresses, amount)
|
||||||
|
return s.estimateMethod(ctx, chainID, contractAddress, fromAddress, "mintTo", usersAddresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) mintAssetsGasUnits(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (uint64, error) {
|
||||||
|
err := s.ValidateWalletsAndAmounts(walletAddresses, amount)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
usersAddresses, amountsList := prepareMintAssetsData(walletAddresses, amount)
|
||||||
|
return s.estimateMethod(ctx, chainID, contractAddress, fromAddress, "mintTo", usersAddresses, amountsList)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) mintTokensGasUnits(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (uint64, error) {
|
||||||
|
tokenType, err := s.db.GetTokenType(chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch tokenType {
|
||||||
|
case protobuf.CommunityTokenType_ERC721:
|
||||||
|
return s.mintCollectiblesGasUnits(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
||||||
|
case protobuf.CommunityTokenType_ERC20:
|
||||||
|
return s.mintAssetsGasUnits(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("unknown token type: %v", tokenType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) prepareCommunityTokenFees(ctx context.Context, from common.Address, to *common.Address, gasUnits uint64, chainID uint64) (*CommunityTokenFees, error) {
|
||||||
|
suggestedFees, err := s.feeManager.SuggestedFees(ctx, chainID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
txArgs := s.suggestedFeesToSendTxArgs(from, to, gasUnits, suggestedFees)
|
||||||
|
|
||||||
|
l1Fee, err := s.estimateL1Fee(ctx, chainID, txArgs)
|
||||||
|
if err == nil {
|
||||||
|
suggestedFees.L1GasFee = weiToGwei(big.NewInt(int64(l1Fee)))
|
||||||
|
}
|
||||||
|
return &CommunityTokenFees{
|
||||||
|
GasUnits: gasUnits,
|
||||||
|
SuggestedFees: suggestedFees,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) suggestedFeesToSendTxArgs(from common.Address, to *common.Address, gas uint64, suggestedFees *wallet.SuggestedFees) transactions.SendTxArgs {
|
||||||
|
sendArgs := transactions.SendTxArgs{}
|
||||||
|
sendArgs.From = types.Address(from)
|
||||||
|
sendArgs.To = (*types.Address)(to)
|
||||||
|
sendArgs.Gas = (*hexutil.Uint64)(&gas)
|
||||||
|
if suggestedFees.EIP1559Enabled {
|
||||||
|
sendArgs.MaxPriorityFeePerGas = (*hexutil.Big)(gweiToWei(suggestedFees.MaxPriorityFeePerGas))
|
||||||
|
sendArgs.MaxFeePerGas = (*hexutil.Big)(gweiToWei(suggestedFees.MaxFeePerGasMedium))
|
||||||
|
} else {
|
||||||
|
sendArgs.GasPrice = (*hexutil.Big)(gweiToWei(suggestedFees.GasPrice))
|
||||||
|
}
|
||||||
|
return sendArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) estimateL1Fee(ctx context.Context, chainID uint64, sendArgs transactions.SendTxArgs) (uint64, error) {
|
||||||
|
transaction, err := s.transactor.ValidateAndBuildTransaction(chainID, sendArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.feeManager.GetL1Fee(ctx, chainID, transaction)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) estimateMethodForTokenInstance(ctx context.Context, contractInstance TokenInstance, chainID uint64, contractAddress string, fromAddress string, methodName string, args ...interface{}) (uint64, error) {
|
||||||
|
ethClient, err := s.manager.rpcClient.EthClient(chainID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err.Error())
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := contractInstance.PackMethod(ctx, methodName, args...)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
toAddr := common.HexToAddress(contractAddress)
|
||||||
|
fromAddr := common.HexToAddress(fromAddress)
|
||||||
|
|
||||||
|
callMsg := ethereum.CallMsg{
|
||||||
|
From: fromAddr,
|
||||||
|
To: &toAddr,
|
||||||
|
Value: big.NewInt(0),
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return estimate + uint64(float32(estimate)*0.1), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) estimateMethod(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, methodName string, args ...interface{}) (uint64, error) {
|
||||||
|
contractInst, err := NewTokenInstance(s, chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return s.estimateMethodForTokenInstance(ctx, contractInst, chainID, contractAddress, fromAddress, methodName, args...)
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
ethRpc "github.com/ethereum/go-ethereum/rpc"
|
ethRpc "github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/status-im/status-go/account"
|
"github.com/status-im/status-go/account"
|
||||||
|
"github.com/status-im/status-go/contracts/community-tokens/mastertoken"
|
||||||
"github.com/status-im/status-go/contracts/community-tokens/ownertoken"
|
"github.com/status-im/status-go/contracts/community-tokens/ownertoken"
|
||||||
communityownertokenregistry "github.com/status-im/status-go/contracts/community-tokens/registry"
|
communityownertokenregistry "github.com/status-im/status-go/contracts/community-tokens/registry"
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
@ -28,6 +29,7 @@ import (
|
||||||
"github.com/status-im/status-go/rpc"
|
"github.com/status-im/status-go/rpc"
|
||||||
"github.com/status-im/status-go/services/communitytokens/communitytokensdatabase"
|
"github.com/status-im/status-go/services/communitytokens/communitytokensdatabase"
|
||||||
"github.com/status-im/status-go/services/utils"
|
"github.com/status-im/status-go/services/utils"
|
||||||
|
"github.com/status-im/status-go/services/wallet"
|
||||||
"github.com/status-im/status-go/services/wallet/bigint"
|
"github.com/status-im/status-go/services/wallet/bigint"
|
||||||
wcommon "github.com/status-im/status-go/services/wallet/common"
|
wcommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/services/wallet/walletevent"
|
"github.com/status-im/status-go/services/wallet/walletevent"
|
||||||
|
@ -45,11 +47,13 @@ type Service struct {
|
||||||
Messenger *protocol.Messenger
|
Messenger *protocol.Messenger
|
||||||
walletFeed *event.Feed
|
walletFeed *event.Feed
|
||||||
walletWatcher *walletevent.Watcher
|
walletWatcher *walletevent.Watcher
|
||||||
|
transactor *transactions.Transactor
|
||||||
|
feeManager *wallet.FeeManager
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a new Collectibles Service.
|
// Returns a new Collectibles Service.
|
||||||
func NewService(rpcClient *rpc.Client, accountsManager *account.GethManager, pendingTracker *transactions.PendingTxTracker,
|
func NewService(rpcClient *rpc.Client, accountsManager *account.GethManager, pendingTracker *transactions.PendingTxTracker,
|
||||||
config *params.NodeConfig, appDb *sql.DB, walletFeed *event.Feed) *Service {
|
config *params.NodeConfig, appDb *sql.DB, walletFeed *event.Feed, transactor *transactions.Transactor) *Service {
|
||||||
return &Service{
|
return &Service{
|
||||||
manager: &Manager{rpcClient: rpcClient},
|
manager: &Manager{rpcClient: rpcClient},
|
||||||
accountsManager: accountsManager,
|
accountsManager: accountsManager,
|
||||||
|
@ -57,6 +61,8 @@ func NewService(rpcClient *rpc.Client, accountsManager *account.GethManager, pen
|
||||||
config: config,
|
config: config,
|
||||||
db: communitytokensdatabase.NewCommunityTokensDatabase(appDb),
|
db: communitytokensdatabase.NewCommunityTokensDatabase(appDb),
|
||||||
walletFeed: walletFeed,
|
walletFeed: walletFeed,
|
||||||
|
transactor: transactor,
|
||||||
|
feeManager: &wallet.FeeManager{RPCClient: rpcClient},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +278,110 @@ func (s *Service) NewOwnerTokenInstance(chainID uint64, contractAddress string)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) NewMasterTokenInstance(chainID uint64, contractAddress string) (*mastertoken.MasterToken, error) {
|
||||||
|
backend, err := s.manager.rpcClient.EthClient(chainID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return mastertoken.NewMasterToken(common.HexToAddress(contractAddress), backend)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) validateTokens(tokenIds []*bigint.BigInt) error {
|
||||||
|
if len(tokenIds) == 0 {
|
||||||
|
return errors.New("token list is empty")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) validateBurnAmount(ctx context.Context, burnAmount *bigint.BigInt, chainID uint64, contractAddress string) error {
|
||||||
|
if burnAmount.Cmp(big.NewInt(0)) <= 0 {
|
||||||
|
return errors.New("burnAmount is less than 0")
|
||||||
|
}
|
||||||
|
remainingSupply, err := s.remainingSupply(ctx, chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if burnAmount.Cmp(remainingSupply.Int) > 1 {
|
||||||
|
return errors.New("burnAmount is bigger than remaining amount")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) remainingSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
||||||
|
tokenType, err := s.db.GetTokenType(chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch tokenType {
|
||||||
|
case protobuf.CommunityTokenType_ERC721:
|
||||||
|
return s.remainingCollectiblesSupply(ctx, chainID, contractAddress)
|
||||||
|
case protobuf.CommunityTokenType_ERC20:
|
||||||
|
return s.remainingAssetsSupply(ctx, chainID, contractAddress)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown token type: %v", tokenType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) prepareNewMaxSupply(ctx context.Context, chainID uint64, contractAddress string, burnAmount *bigint.BigInt) (*big.Int, error) {
|
||||||
|
maxSupply, err := s.maxSupply(ctx, chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var newMaxSupply = new(big.Int)
|
||||||
|
newMaxSupply.Sub(maxSupply, burnAmount.Int)
|
||||||
|
return newMaxSupply, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemainingSupply = MaxSupply - MintedCount
|
||||||
|
func (s *Service) remainingCollectiblesSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
||||||
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
||||||
|
contractInst, err := s.manager.NewCollectiblesInstance(chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
maxSupply, err := contractInst.MaxSupply(callOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mintedCount, err := contractInst.MintedCount(callOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var res = new(big.Int)
|
||||||
|
res.Sub(maxSupply, mintedCount)
|
||||||
|
return &bigint.BigInt{Int: res}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemainingSupply = MaxSupply - TotalSupply
|
||||||
|
func (s *Service) remainingAssetsSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
||||||
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
||||||
|
contractInst, err := s.manager.NewAssetsInstance(chainID, contractAddress)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
maxSupply, err := contractInst.MaxSupply(callOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
totalSupply, err := contractInst.TotalSupply(callOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var res = new(big.Int)
|
||||||
|
res.Sub(maxSupply, totalSupply)
|
||||||
|
return &bigint.BigInt{Int: res}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) ValidateWalletsAndAmounts(walletAddresses []string, amount *bigint.BigInt) error {
|
||||||
|
if len(walletAddresses) == 0 {
|
||||||
|
return errors.New("wallet addresses list is empty")
|
||||||
|
}
|
||||||
|
if amount.Cmp(big.NewInt(0)) <= 0 {
|
||||||
|
return errors.New("amount is <= 0")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) GetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
func (s *Service) GetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
||||||
|
|
||||||
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
||||||
|
|
|
@ -55,7 +55,6 @@ func (t OwnerTokenInstance) PackMethod(ctx context.Context, methodName string, a
|
||||||
type MasterTokenInstance struct {
|
type MasterTokenInstance struct {
|
||||||
TokenInstance
|
TokenInstance
|
||||||
instance *mastertoken.MasterToken
|
instance *mastertoken.MasterToken
|
||||||
api *API
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t MasterTokenInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*big.Int) (*types.Transaction, error) {
|
func (t MasterTokenInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*big.Int) (*types.Transaction, error) {
|
||||||
|
@ -63,7 +62,7 @@ func (t MasterTokenInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t MasterTokenInstance) Mint(transactOpts *bind.TransactOpts, walletAddresses []string, amount *bigint.BigInt) (*types.Transaction, error) {
|
func (t MasterTokenInstance) Mint(transactOpts *bind.TransactOpts, walletAddresses []string, amount *bigint.BigInt) (*types.Transaction, error) {
|
||||||
usersAddresses := t.api.PrepareMintCollectiblesData(walletAddresses, amount)
|
usersAddresses := prepareMintCollectiblesData(walletAddresses, amount)
|
||||||
return t.instance.MintTo(transactOpts, usersAddresses)
|
return t.instance.MintTo(transactOpts, usersAddresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +82,6 @@ func (t MasterTokenInstance) PackMethod(ctx context.Context, methodName string,
|
||||||
type CollectibleInstance struct {
|
type CollectibleInstance struct {
|
||||||
TokenInstance
|
TokenInstance
|
||||||
instance *collectibles.Collectibles
|
instance *collectibles.Collectibles
|
||||||
api *API
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t CollectibleInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*big.Int) (*types.Transaction, error) {
|
func (t CollectibleInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*big.Int) (*types.Transaction, error) {
|
||||||
|
@ -91,7 +89,7 @@ func (t CollectibleInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t CollectibleInstance) Mint(transactOpts *bind.TransactOpts, walletAddresses []string, amount *bigint.BigInt) (*types.Transaction, error) {
|
func (t CollectibleInstance) Mint(transactOpts *bind.TransactOpts, walletAddresses []string, amount *bigint.BigInt) (*types.Transaction, error) {
|
||||||
usersAddresses := t.api.PrepareMintCollectiblesData(walletAddresses, amount)
|
usersAddresses := prepareMintCollectiblesData(walletAddresses, amount)
|
||||||
return t.instance.MintTo(transactOpts, usersAddresses)
|
return t.instance.MintTo(transactOpts, usersAddresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +109,6 @@ func (t CollectibleInstance) PackMethod(ctx context.Context, methodName string,
|
||||||
type AssetInstance struct {
|
type AssetInstance struct {
|
||||||
TokenInstance
|
TokenInstance
|
||||||
instance *assets.Assets
|
instance *assets.Assets
|
||||||
api *API
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t AssetInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*big.Int) (*types.Transaction, error) {
|
func (t AssetInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*big.Int) (*types.Transaction, error) {
|
||||||
|
@ -121,7 +118,7 @@ func (t AssetInstance) RemoteBurn(transactOpts *bind.TransactOpts, tokenIds []*b
|
||||||
// The amount should be in smallest denomination of the asset (like wei) with decimal = 18, eg.
|
// The amount should be in smallest denomination of the asset (like wei) with decimal = 18, eg.
|
||||||
// if we want to mint 2.34 of the token, then amount should be 234{16 zeros}.
|
// if we want to mint 2.34 of the token, then amount should be 234{16 zeros}.
|
||||||
func (t AssetInstance) Mint(transactOpts *bind.TransactOpts, walletAddresses []string, amount *bigint.BigInt) (*types.Transaction, error) {
|
func (t AssetInstance) Mint(transactOpts *bind.TransactOpts, walletAddresses []string, amount *bigint.BigInt) (*types.Transaction, error) {
|
||||||
usersAddresses, amountsList := t.api.PrepareMintAssetsData(walletAddresses, amount)
|
usersAddresses, amountsList := prepareMintAssetsData(walletAddresses, amount)
|
||||||
return t.instance.MintTo(transactOpts, usersAddresses, amountsList)
|
return t.instance.MintTo(transactOpts, usersAddresses, amountsList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,36 +136,36 @@ func (t AssetInstance) PackMethod(ctx context.Context, methodName string, args .
|
||||||
|
|
||||||
// creator
|
// creator
|
||||||
|
|
||||||
func NewTokenInstance(api *API, chainID uint64, contractAddress string) (TokenInstance, error) {
|
func NewTokenInstance(s *Service, chainID uint64, contractAddress string) (TokenInstance, error) {
|
||||||
tokenType, err := api.s.db.GetTokenType(chainID, contractAddress)
|
tokenType, err := s.db.GetTokenType(chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
privLevel, err := api.s.db.GetTokenPrivilegesLevel(chainID, contractAddress)
|
privLevel, err := s.db.GetTokenPrivilegesLevel(chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case privLevel == token.OwnerLevel:
|
case privLevel == token.OwnerLevel:
|
||||||
contractInst, err := api.NewOwnerTokenInstance(chainID, contractAddress)
|
contractInst, err := s.NewOwnerTokenInstance(chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &OwnerTokenInstance{instance: contractInst}, nil
|
return &OwnerTokenInstance{instance: contractInst}, nil
|
||||||
case privLevel == token.MasterLevel:
|
case privLevel == token.MasterLevel:
|
||||||
contractInst, err := api.NewMasterTokenInstance(chainID, contractAddress)
|
contractInst, err := s.NewMasterTokenInstance(chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &MasterTokenInstance{instance: contractInst}, nil
|
return &MasterTokenInstance{instance: contractInst}, nil
|
||||||
case tokenType == protobuf.CommunityTokenType_ERC721:
|
case tokenType == protobuf.CommunityTokenType_ERC721:
|
||||||
contractInst, err := api.NewCollectiblesInstance(chainID, contractAddress)
|
contractInst, err := s.manager.NewCollectiblesInstance(chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &CollectibleInstance{instance: contractInst}, nil
|
return &CollectibleInstance{instance: contractInst}, nil
|
||||||
case tokenType == protobuf.CommunityTokenType_ERC20:
|
case tokenType == protobuf.CommunityTokenType_ERC20:
|
||||||
contractInst, err := api.NewAssetsInstance(chainID, contractAddress)
|
contractInst, err := s.manager.NewAssetsInstance(chainID, contractAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -412,7 +412,7 @@ func (api *API) FetchTokenDetails(ctx context.Context, symbols []string) (map[st
|
||||||
|
|
||||||
func (api *API) GetSuggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) {
|
func (api *API) GetSuggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) {
|
||||||
log.Debug("call to GetSuggestedFees")
|
log.Debug("call to GetSuggestedFees")
|
||||||
return api.s.feesManager.suggestedFees(ctx, chainID)
|
return api.s.feesManager.SuggestedFees(ctx, chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) GetEstimatedLatestBlockNumber(ctx context.Context, chainID uint64) (uint64, error) {
|
func (api *API) GetEstimatedLatestBlockNumber(ctx context.Context, chainID uint64) (uint64, error) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ func gweiToWei(val *big.Float) *big.Int {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FeeManager) suggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) {
|
func (f *FeeManager) SuggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) {
|
||||||
backend, err := f.RPCClient.EthClient(chainID)
|
backend, err := f.RPCClient.EthClient(chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -256,8 +256,7 @@ func (f *FeeManager) getFeeHistorySorted(chainID uint64) ([]*big.Int, error) {
|
||||||
return fees, nil
|
return fees, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FeeManager) getL1Fee(ctx context.Context, chainID uint64, tx *ethTypes.Transaction) (uint64, error) {
|
func (f *FeeManager) GetL1Fee(ctx context.Context, chainID uint64, tx *ethTypes.Transaction) (uint64, error) {
|
||||||
|
|
||||||
ethClient, err := f.RPCClient.EthClient(chainID)
|
ethClient, err := f.RPCClient.EthClient(chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -646,7 +646,7 @@ func (r *Router) suggestedRoutes(
|
||||||
}
|
}
|
||||||
|
|
||||||
group.Add(func(c context.Context) error {
|
group.Add(func(c context.Context) error {
|
||||||
gasFees, err := r.s.feesManager.suggestedFees(ctx, network.ChainID)
|
gasFees, err := r.s.feesManager.SuggestedFees(ctx, network.ChainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -747,7 +747,7 @@ func (r *Router) suggestedRoutes(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
l1GasFeeWei, _ = r.s.feesManager.getL1Fee(ctx, network.ChainID, tx)
|
l1GasFeeWei, _ = r.s.feesManager.GetL1Fee(ctx, network.ChainID, tx)
|
||||||
l1GasFeeWei += l1ApprovalFee
|
l1GasFeeWei += l1ApprovalFee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue