2023-08-25 15:36:39 +00:00
|
|
|
package communitytokens
|
2023-01-12 15:17:21 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"math/big"
|
|
|
|
|
2024-03-14 08:39:06 +00:00
|
|
|
"github.com/pkg/errors"
|
2024-10-28 20:54:17 +00:00
|
|
|
"go.uber.org/zap"
|
2024-03-14 08:39:06 +00:00
|
|
|
|
2023-03-10 14:09:34 +00:00
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2024-04-05 14:00:32 +00:00
|
|
|
|
2023-07-18 08:33:45 +00:00
|
|
|
"github.com/status-im/status-go/contracts/community-tokens/assets"
|
|
|
|
"github.com/status-im/status-go/contracts/community-tokens/collectibles"
|
2023-08-29 13:17:37 +00:00
|
|
|
communitytokendeployer "github.com/status-im/status-go/contracts/community-tokens/deployer"
|
2023-07-18 08:33:45 +00:00
|
|
|
"github.com/status-im/status-go/contracts/community-tokens/ownertoken"
|
2023-08-29 13:17:37 +00:00
|
|
|
communityownertokenregistry "github.com/status-im/status-go/contracts/community-tokens/registry"
|
2023-07-18 08:33:45 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/crypto"
|
2024-03-14 08:39:06 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/types"
|
|
|
|
"github.com/status-im/status-go/images"
|
2024-10-28 20:54:17 +00:00
|
|
|
"github.com/status-im/status-go/logutils"
|
2024-03-14 08:39:06 +00:00
|
|
|
"github.com/status-im/status-go/protocol/communities/token"
|
2023-06-14 07:47:54 +00:00
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
2023-01-12 15:17:21 +00:00
|
|
|
"github.com/status-im/status-go/services/utils"
|
2023-05-05 11:03:06 +00:00
|
|
|
"github.com/status-im/status-go/services/wallet/bigint"
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon "github.com/status-im/status-go/services/wallet/common"
|
2023-01-12 15:17:21 +00:00
|
|
|
"github.com/status-im/status-go/transactions"
|
|
|
|
)
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
func NewAPI(s *Service) *API {
|
2023-01-12 15:17:21 +00:00
|
|
|
return &API{
|
2023-08-22 17:48:42 +00:00
|
|
|
s: s,
|
2023-01-12 15:17:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type API struct {
|
2023-08-22 17:48:42 +00:00
|
|
|
s *Service
|
2023-01-12 15:17:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type DeploymentDetails struct {
|
2024-03-14 08:39:06 +00:00
|
|
|
ContractAddress string `json:"contractAddress"`
|
|
|
|
TransactionHash string `json:"transactionHash"`
|
|
|
|
CommunityToken *token.CommunityToken `json:"communityToken"`
|
|
|
|
OwnerToken *token.CommunityToken `json:"ownerToken"`
|
|
|
|
MasterToken *token.CommunityToken `json:"masterToken"`
|
2023-01-12 15:17:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const maxSupply = 999999999
|
|
|
|
|
|
|
|
type DeploymentParameters struct {
|
2024-03-14 08:39:06 +00:00
|
|
|
Name string `json:"name"`
|
|
|
|
Symbol string `json:"symbol"`
|
|
|
|
Supply *bigint.BigInt `json:"supply"`
|
|
|
|
InfiniteSupply bool `json:"infiniteSupply"`
|
|
|
|
Transferable bool `json:"transferable"`
|
|
|
|
RemoteSelfDestruct bool `json:"remoteSelfDestruct"`
|
|
|
|
TokenURI string `json:"tokenUri"`
|
|
|
|
OwnerTokenAddress string `json:"ownerTokenAddress"`
|
|
|
|
MasterTokenAddress string `json:"masterTokenAddress"`
|
|
|
|
CommunityID string `json:"communityId"`
|
|
|
|
Description string `json:"description"`
|
|
|
|
CroppedImage *images.CroppedImage `json:"croppedImage,omitempty"` // for community tokens
|
|
|
|
Base64Image string `json:"base64image"` // for owner & master tokens
|
|
|
|
Decimals int `json:"decimals"`
|
2023-01-12 15:17:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *DeploymentParameters) GetSupply() *big.Int {
|
|
|
|
if d.InfiniteSupply {
|
|
|
|
return d.GetInfiniteSupply()
|
|
|
|
}
|
2023-06-21 11:20:43 +00:00
|
|
|
return d.Supply.Int
|
2023-01-12 15:17:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// infinite supply for ERC721 is 2^256-1
|
|
|
|
func (d *DeploymentParameters) GetInfiniteSupply() *big.Int {
|
2023-07-07 13:03:37 +00:00
|
|
|
return GetInfiniteSupply()
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetInfiniteSupply() *big.Int {
|
2023-01-12 15:17:21 +00:00
|
|
|
max := new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil)
|
|
|
|
max.Sub(max, big.NewInt(1))
|
|
|
|
return max
|
|
|
|
}
|
|
|
|
|
2023-06-21 11:20:43 +00:00
|
|
|
func (d *DeploymentParameters) Validate(isAsset bool) error {
|
2023-01-12 15:17:21 +00:00
|
|
|
if len(d.Name) <= 0 {
|
|
|
|
return errors.New("empty collectible name")
|
|
|
|
}
|
|
|
|
if len(d.Symbol) <= 0 {
|
|
|
|
return errors.New("empty collectible symbol")
|
|
|
|
}
|
2023-06-21 11:20:43 +00:00
|
|
|
var maxForType = big.NewInt(maxSupply)
|
|
|
|
if isAsset {
|
|
|
|
assetMultiplier, _ := big.NewInt(0).SetString("1000000000000000000", 10)
|
|
|
|
maxForType = maxForType.Mul(maxForType, assetMultiplier)
|
|
|
|
}
|
|
|
|
if !d.InfiniteSupply && (d.Supply.Cmp(big.NewInt(0)) < 0 || d.Supply.Cmp(maxForType) > 0) {
|
2023-01-12 15:17:21 +00:00
|
|
|
return fmt.Errorf("wrong supply value: %v", d.Supply)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-06-14 07:47:54 +00:00
|
|
|
func (api *API) DeployCollectibles(ctx context.Context, chainID uint64, deploymentParameters DeploymentParameters, txArgs transactions.SendTxArgs, password string) (DeploymentDetails, error) {
|
2023-06-21 11:20:43 +00:00
|
|
|
err := deploymentParameters.Validate(false)
|
2023-01-12 15:17:21 +00:00
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
2023-08-22 17:48:42 +00:00
|
|
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
2023-01-12 15:17:21 +00:00
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
ethClient, err := api.s.manager.rpcClient.EthClient(chainID)
|
2023-01-12 15:17:21 +00:00
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error(err.Error())
|
2023-01-12 15:17:21 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
address, tx, _, err := collectibles.DeployCollectibles(transactOpts, ethClient, deploymentParameters.Name,
|
|
|
|
deploymentParameters.Symbol, deploymentParameters.GetSupply(),
|
|
|
|
deploymentParameters.RemoteSelfDestruct, deploymentParameters.Transferable,
|
2023-07-18 08:33:45 +00:00
|
|
|
deploymentParameters.TokenURI, common.HexToAddress(deploymentParameters.OwnerTokenAddress),
|
|
|
|
common.HexToAddress(deploymentParameters.MasterTokenAddress))
|
2023-01-12 15:17:21 +00:00
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error(err.Error())
|
2023-01-12 15:17:21 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
err = api.s.pendingTracker.TrackPendingTransaction(
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon.ChainID(chainID),
|
|
|
|
tx.Hash(),
|
|
|
|
common.Address(txArgs.From),
|
2024-03-14 08:39:06 +00:00
|
|
|
address,
|
2023-08-01 18:50:30 +00:00
|
|
|
transactions.DeployCommunityToken,
|
2024-03-14 08:39:06 +00:00
|
|
|
transactions.Keep,
|
|
|
|
"",
|
2023-08-01 18:50:30 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("TrackPendingTransaction error", zap.Error(err))
|
2023-08-01 18:50:30 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
2023-07-18 13:32:31 +00:00
|
|
|
|
2024-03-14 08:39:06 +00:00
|
|
|
savedCommunityToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), deploymentParameters, txArgs.From.Hex(), address.Hex(),
|
2024-05-21 08:51:48 +00:00
|
|
|
protobuf.CommunityTokenType_ERC721, token.CommunityLevel, tx.Hash().Hex())
|
2024-03-14 08:39:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return DeploymentDetails{
|
|
|
|
ContractAddress: address.Hex(),
|
|
|
|
TransactionHash: tx.Hash().Hex(),
|
|
|
|
CommunityToken: savedCommunityToken}, nil
|
2023-01-12 15:17:21 +00:00
|
|
|
}
|
2023-03-10 14:09:34 +00:00
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
func decodeSignature(sig []byte) (r [32]byte, s [32]byte, v uint8, err error) {
|
|
|
|
if len(sig) != crypto.SignatureLength {
|
|
|
|
return [32]byte{}, [32]byte{}, 0, fmt.Errorf("wrong size for signature: got %d, want %d", len(sig), crypto.SignatureLength)
|
|
|
|
}
|
|
|
|
copy(r[:], sig[:32])
|
|
|
|
copy(s[:], sig[32:64])
|
|
|
|
v = sig[64] + 27
|
|
|
|
return r, s, v, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func prepareDeploymentSignatureStruct(signature string, communityID string, addressFrom common.Address) (communitytokendeployer.CommunityTokenDeployerDeploymentSignature, error) {
|
|
|
|
r, s, v, err := decodeSignature(common.FromHex(signature))
|
|
|
|
if err != nil {
|
|
|
|
return communitytokendeployer.CommunityTokenDeployerDeploymentSignature{}, err
|
|
|
|
}
|
|
|
|
communityEthAddress, err := convert33BytesPubKeyToEthAddress(communityID)
|
|
|
|
if err != nil {
|
|
|
|
return communitytokendeployer.CommunityTokenDeployerDeploymentSignature{}, err
|
|
|
|
}
|
|
|
|
communitySignature := communitytokendeployer.CommunityTokenDeployerDeploymentSignature{
|
|
|
|
V: v,
|
|
|
|
R: r,
|
|
|
|
S: s,
|
|
|
|
Deployer: addressFrom,
|
|
|
|
Signer: communityEthAddress,
|
|
|
|
}
|
|
|
|
return communitySignature, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) DeployOwnerToken(ctx context.Context, chainID uint64,
|
|
|
|
ownerTokenParameters DeploymentParameters, masterTokenParameters DeploymentParameters,
|
2024-03-14 08:39:06 +00:00
|
|
|
signerPubKey string, txArgs transactions.SendTxArgs, password string) (DeploymentDetails, error) {
|
2023-07-18 08:33:45 +00:00
|
|
|
err := ownerTokenParameters.Validate(false)
|
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
if len(signerPubKey) <= 0 {
|
|
|
|
return DeploymentDetails{}, fmt.Errorf("signerPubKey is empty")
|
|
|
|
}
|
|
|
|
|
2023-07-18 08:33:45 +00:00
|
|
|
err = masterTokenParameters.Validate(false)
|
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
2023-07-18 08:33:45 +00:00
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
deployerContractInst, err := api.NewCommunityTokenDeployerInstance(chainID)
|
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, 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,
|
|
|
|
}
|
|
|
|
|
2024-03-14 08:39:06 +00:00
|
|
|
signature, err := api.s.Messenger.CreateCommunityTokenDeploymentSignature(context.Background(), chainID, txArgs.From.Hex(), ownerTokenParameters.CommunityID)
|
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
communitySignature, err := prepareDeploymentSignatureStruct(types.HexBytes(signature).String(), ownerTokenParameters.CommunityID, common.Address(txArgs.From))
|
2023-07-18 08:33:45 +00:00
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Debug("Prepare deployment", zap.Any("signature", communitySignature))
|
2023-08-29 13:17:37 +00:00
|
|
|
|
|
|
|
tx, err := deployerContractInst.Deploy(transactOpts, ownerTokenConfig, masterTokenConfig, communitySignature, common.FromHex(signerPubKey))
|
2023-07-18 08:33:45 +00:00
|
|
|
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error(err.Error())
|
2023-07-18 08:33:45 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Debug("Contract deployed", zap.Stringer("hash", tx.Hash()))
|
2024-03-14 08:39:06 +00:00
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
err = api.s.pendingTracker.TrackPendingTransaction(
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon.ChainID(chainID),
|
|
|
|
tx.Hash(),
|
|
|
|
common.Address(txArgs.From),
|
2024-03-14 08:39:06 +00:00
|
|
|
common.Address{},
|
2023-08-01 18:50:30 +00:00
|
|
|
transactions.DeployOwnerToken,
|
2024-03-14 08:39:06 +00:00
|
|
|
transactions.Keep,
|
|
|
|
"",
|
2023-08-01 18:50:30 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("TrackPendingTransaction error", zap.Error(err))
|
2023-08-01 18:50:30 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
2023-07-18 08:33:45 +00:00
|
|
|
|
2024-03-14 08:39:06 +00:00
|
|
|
savedOwnerToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), ownerTokenParameters, txArgs.From.Hex(),
|
2024-05-21 08:51:48 +00:00
|
|
|
api.s.TemporaryOwnerContractAddress(tx.Hash().Hex()), protobuf.CommunityTokenType_ERC721, token.OwnerLevel, tx.Hash().Hex())
|
2023-07-18 08:33:45 +00:00
|
|
|
if err != nil {
|
2024-03-14 08:39:06 +00:00
|
|
|
return DeploymentDetails{}, err
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
2024-03-14 08:39:06 +00:00
|
|
|
savedMasterToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), masterTokenParameters, txArgs.From.Hex(),
|
2024-05-21 08:51:48 +00:00
|
|
|
api.s.TemporaryMasterContractAddress(tx.Hash().Hex()), protobuf.CommunityTokenType_ERC721, token.MasterLevel, tx.Hash().Hex())
|
2023-08-29 13:17:37 +00:00
|
|
|
if err != nil {
|
2024-03-14 08:39:06 +00:00
|
|
|
return DeploymentDetails{}, err
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
2024-03-14 08:39:06 +00:00
|
|
|
return DeploymentDetails{
|
|
|
|
ContractAddress: "",
|
|
|
|
TransactionHash: tx.Hash().Hex(),
|
|
|
|
OwnerToken: savedOwnerToken,
|
|
|
|
MasterToken: savedMasterToken}, nil
|
2023-07-18 08:33:45 +00:00
|
|
|
}
|
|
|
|
|
2024-05-21 08:51:48 +00:00
|
|
|
// recovery function which starts transaction tracking again
|
|
|
|
func (api *API) ReTrackOwnerTokenDeploymentTransaction(ctx context.Context, chainID uint64, contractAddress string) error {
|
|
|
|
return api.s.ReTrackOwnerTokenDeploymentTransaction(ctx, chainID, contractAddress)
|
|
|
|
}
|
|
|
|
|
2023-06-14 07:47:54 +00:00
|
|
|
func (api *API) DeployAssets(ctx context.Context, chainID uint64, deploymentParameters DeploymentParameters, txArgs transactions.SendTxArgs, password string) (DeploymentDetails, error) {
|
|
|
|
|
2023-06-21 11:20:43 +00:00
|
|
|
err := deploymentParameters.Validate(true)
|
2023-06-14 07:47:54 +00:00
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
2023-06-14 07:47:54 +00:00
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
ethClient, err := api.s.manager.rpcClient.EthClient(chainID)
|
2023-06-14 07:47:54 +00:00
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error(err.Error())
|
2023-06-14 07:47:54 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
const decimals = 18
|
2023-06-14 07:47:54 +00:00
|
|
|
address, tx, _, err := assets.DeployAssets(transactOpts, ethClient, deploymentParameters.Name,
|
2023-10-09 10:01:44 +00:00
|
|
|
deploymentParameters.Symbol, decimals, deploymentParameters.GetSupply(),
|
2023-10-19 06:17:54 +00:00
|
|
|
deploymentParameters.TokenURI,
|
2023-10-09 10:01:44 +00:00
|
|
|
common.HexToAddress(deploymentParameters.OwnerTokenAddress),
|
|
|
|
common.HexToAddress(deploymentParameters.MasterTokenAddress))
|
2023-06-14 07:47:54 +00:00
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error(err.Error())
|
2023-06-14 07:47:54 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
err = api.s.pendingTracker.TrackPendingTransaction(
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon.ChainID(chainID),
|
|
|
|
tx.Hash(),
|
|
|
|
common.Address(txArgs.From),
|
2024-03-14 08:39:06 +00:00
|
|
|
address,
|
2023-08-01 18:50:30 +00:00
|
|
|
transactions.DeployCommunityToken,
|
2024-03-14 08:39:06 +00:00
|
|
|
transactions.Keep,
|
|
|
|
"",
|
2023-08-01 18:50:30 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("TrackPendingTransaction error", zap.Error(err))
|
2023-08-01 18:50:30 +00:00
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
2023-07-18 13:32:31 +00:00
|
|
|
|
2024-03-14 08:39:06 +00:00
|
|
|
savedCommunityToken, err := api.s.CreateCommunityTokenAndSave(int(chainID), deploymentParameters, txArgs.From.Hex(), address.Hex(),
|
2024-05-21 08:51:48 +00:00
|
|
|
protobuf.CommunityTokenType_ERC20, token.CommunityLevel, tx.Hash().Hex())
|
2024-03-14 08:39:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return DeploymentDetails{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return DeploymentDetails{
|
|
|
|
ContractAddress: address.Hex(),
|
|
|
|
TransactionHash: tx.Hash().Hex(),
|
|
|
|
CommunityToken: savedCommunityToken}, nil
|
2023-06-14 07:47:54 +00:00
|
|
|
}
|
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
func (api *API) DeployCollectiblesEstimate(ctx context.Context, chainID uint64, fromAddress string) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.deployCollectiblesEstimate(ctx, chainID, fromAddress)
|
2023-04-03 10:58:36 +00:00
|
|
|
}
|
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
func (api *API) DeployAssetsEstimate(ctx context.Context, chainID uint64, fromAddress string) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.deployAssetsEstimate(ctx, chainID, fromAddress)
|
2023-06-14 07:47:54 +00:00
|
|
|
}
|
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
func (api *API) DeployOwnerTokenEstimate(ctx context.Context, chainID uint64, fromAddress string,
|
|
|
|
ownerTokenParameters DeploymentParameters, masterTokenParameters DeploymentParameters,
|
2024-04-05 14:00:32 +00:00
|
|
|
communityID string, signerPubKey string) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.deployOwnerTokenEstimate(ctx, chainID, fromAddress, ownerTokenParameters, masterTokenParameters, communityID, signerPubKey)
|
|
|
|
}
|
2023-08-29 13:17:37 +00:00
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
func (api *API) EstimateMintTokens(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, walletAddresses []string, amount *bigint.BigInt) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.mintTokensEstimate(ctx, chainID, contractAddress, fromAddress, walletAddresses, amount)
|
|
|
|
}
|
2023-08-29 13:17:37 +00:00
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
// This is only ERC721 function
|
|
|
|
func (api *API) EstimateRemoteBurn(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, tokenIds []*bigint.BigInt) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.remoteBurnEstimate(ctx, chainID, contractAddress, fromAddress, tokenIds)
|
|
|
|
}
|
2023-08-29 13:17:37 +00:00
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
func (api *API) EstimateBurn(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, burnAmount *bigint.BigInt) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.burnEstimate(ctx, chainID, contractAddress, fromAddress, burnAmount)
|
2023-07-18 08:33:45 +00:00
|
|
|
}
|
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
func (api *API) EstimateSetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string, fromAddress string, newSignerPubKey string) (*CommunityTokenFees, error) {
|
|
|
|
return api.s.setSignerPubKeyEstimate(ctx, chainID, contractAddress, fromAddress, newSignerPubKey)
|
2023-08-14 08:27:46 +00:00
|
|
|
}
|
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
func (api *API) NewOwnerTokenInstance(chainID uint64, contractAddress string) (*ownertoken.OwnerToken, error) {
|
2023-07-05 17:35:22 +00:00
|
|
|
return api.s.NewOwnerTokenInstance(chainID, contractAddress)
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) NewCommunityTokenDeployerInstance(chainID uint64) (*communitytokendeployer.CommunityTokenDeployer, error) {
|
|
|
|
return api.s.manager.NewCommunityTokenDeployerInstance(chainID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) NewCommunityOwnerTokenRegistryInstance(chainID uint64, contractAddress string) (*communityownertokenregistry.CommunityOwnerTokenRegistry, error) {
|
2023-07-05 17:35:22 +00:00
|
|
|
return api.s.NewCommunityOwnerTokenRegistryInstance(chainID, contractAddress)
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
2023-08-14 08:27:46 +00:00
|
|
|
func (api *API) NewCollectiblesInstance(chainID uint64, contractAddress string) (*collectibles.Collectibles, error) {
|
2023-08-22 17:48:42 +00:00
|
|
|
return api.s.manager.NewCollectiblesInstance(chainID, contractAddress)
|
2023-03-10 14:09:34 +00:00
|
|
|
}
|
|
|
|
|
2023-08-14 08:27:46 +00:00
|
|
|
func (api *API) NewAssetsInstance(chainID uint64, contractAddress string) (*assets.Assets, error) {
|
2023-08-22 17:48:42 +00:00
|
|
|
return api.s.manager.NewAssetsInstance(chainID, contractAddress)
|
2023-06-14 07:47:54 +00:00
|
|
|
}
|
|
|
|
|
2023-08-14 08:27:46 +00:00
|
|
|
// Universal minting function for every type of token.
|
2023-06-21 11:20:43 +00:00
|
|
|
func (api *API) MintTokens(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, walletAddresses []string, amount *bigint.BigInt) (string, error) {
|
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
err := api.s.ValidateWalletsAndAmounts(walletAddresses, amount)
|
2023-04-04 13:53:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
2023-03-10 14:09:34 +00:00
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
2023-08-14 08:27:46 +00:00
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
contractInst, err := NewTokenInstance(api.s, chainID, contractAddress)
|
2023-03-10 14:09:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:27:46 +00:00
|
|
|
tx, err := contractInst.Mint(transactOpts, walletAddresses, amount)
|
2023-03-10 14:09:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
err = api.s.pendingTracker.TrackPendingTransaction(
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon.ChainID(chainID),
|
|
|
|
tx.Hash(),
|
|
|
|
common.Address(txArgs.From),
|
2024-03-14 08:39:06 +00:00
|
|
|
common.HexToAddress(contractAddress),
|
2023-08-01 18:50:30 +00:00
|
|
|
transactions.AirdropCommunityToken,
|
2024-03-14 08:39:06 +00:00
|
|
|
transactions.Keep,
|
|
|
|
"",
|
2023-08-01 18:50:30 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("TrackPendingTransaction error", zap.Error(err))
|
2023-08-01 18:50:30 +00:00
|
|
|
return "", err
|
|
|
|
}
|
2023-07-18 13:32:31 +00:00
|
|
|
|
2023-03-10 14:09:34 +00:00
|
|
|
return tx.Hash().Hex(), nil
|
|
|
|
}
|
|
|
|
|
2023-07-13 08:57:37 +00:00
|
|
|
// This is only ERC721 function
|
|
|
|
func (api *API) RemoteDestructedAmount(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
|
|
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
2023-08-14 08:27:46 +00:00
|
|
|
contractInst, err := api.NewCollectiblesInstance(chainID, contractAddress)
|
2023-07-13 08:57:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// total supply = airdropped only (w/o burnt)
|
|
|
|
totalSupply, err := contractInst.TotalSupply(callOpts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// minted = all created tokens (airdropped and remotely destructed)
|
|
|
|
mintedCount, err := contractInst.MintedCount(callOpts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var res = new(big.Int)
|
|
|
|
res.Sub(mintedCount, totalSupply)
|
|
|
|
|
|
|
|
return &bigint.BigInt{Int: res}, nil
|
|
|
|
}
|
|
|
|
|
2023-06-14 07:47:54 +00:00
|
|
|
// This is only ERC721 function
|
2024-03-14 08:39:06 +00:00
|
|
|
func (api *API) RemoteBurn(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, tokenIds []*bigint.BigInt, additionalData string) (string, error) {
|
2024-04-05 14:00:32 +00:00
|
|
|
err := api.s.validateTokens(tokenIds)
|
2023-06-02 08:07:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
2023-05-05 11:03:06 +00:00
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
2023-05-05 11:03:06 +00:00
|
|
|
|
|
|
|
var tempTokenIds []*big.Int
|
|
|
|
for _, v := range tokenIds {
|
|
|
|
tempTokenIds = append(tempTokenIds, v.Int)
|
|
|
|
}
|
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
contractInst, err := NewTokenInstance(api.s, chainID, contractAddress)
|
2023-08-14 08:27:46 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-05-05 11:03:06 +00:00
|
|
|
tx, err := contractInst.RemoteBurn(transactOpts, tempTokenIds)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
err = api.s.pendingTracker.TrackPendingTransaction(
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon.ChainID(chainID),
|
|
|
|
tx.Hash(),
|
|
|
|
common.Address(txArgs.From),
|
2024-03-14 08:39:06 +00:00
|
|
|
common.HexToAddress(contractAddress),
|
2023-08-01 18:50:30 +00:00
|
|
|
transactions.RemoteDestructCollectible,
|
2024-03-14 08:39:06 +00:00
|
|
|
transactions.Keep,
|
|
|
|
additionalData,
|
2023-08-01 18:50:30 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("TrackPendingTransaction error", zap.Error(err))
|
2023-08-01 18:50:30 +00:00
|
|
|
return "", err
|
|
|
|
}
|
2023-07-18 13:32:31 +00:00
|
|
|
|
2023-05-05 11:03:06 +00:00
|
|
|
return tx.Hash().Hex(), nil
|
|
|
|
}
|
|
|
|
|
2023-07-18 08:33:45 +00:00
|
|
|
func (api *API) GetCollectiblesContractInstance(chainID uint64, contractAddress string) (*collectibles.Collectibles, error) {
|
2023-08-22 17:48:42 +00:00
|
|
|
return api.s.manager.GetCollectiblesContractInstance(chainID, contractAddress)
|
2023-07-07 13:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) GetAssetContractInstance(chainID uint64, contractAddress string) (*assets.Assets, error) {
|
2023-08-22 17:48:42 +00:00
|
|
|
return api.s.manager.GetAssetContractInstance(chainID, contractAddress)
|
2023-07-07 13:03:37 +00:00
|
|
|
}
|
|
|
|
|
2023-06-21 11:20:43 +00:00
|
|
|
func (api *API) RemainingSupply(ctx context.Context, chainID uint64, contractAddress string) (*bigint.BigInt, error) {
|
2024-04-05 14:00:32 +00:00
|
|
|
return api.s.remainingSupply(ctx, chainID, contractAddress)
|
2023-06-21 11:20:43 +00:00
|
|
|
}
|
2023-06-02 08:07:00 +00:00
|
|
|
|
2023-06-21 11:20:43 +00:00
|
|
|
func (api *API) Burn(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, burnAmount *bigint.BigInt) (string, error) {
|
2024-04-05 14:00:32 +00:00
|
|
|
err := api.s.validateBurnAmount(ctx, burnAmount, chainID, contractAddress)
|
2023-06-02 08:07:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
transactOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.s.accountsManager, api.s.config.KeyStoreDir, txArgs.From, password))
|
2023-06-02 08:07:00 +00:00
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
newMaxSupply, err := api.s.prepareNewMaxSupply(ctx, chainID, contractAddress, burnAmount)
|
2023-06-02 08:07:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2024-04-05 14:00:32 +00:00
|
|
|
contractInst, err := NewTokenInstance(api.s, chainID, contractAddress)
|
2023-08-14 08:27:46 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
tx, err := contractInst.SetMaxSupply(transactOpts, newMaxSupply)
|
2023-06-02 08:07:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-08-22 17:48:42 +00:00
|
|
|
err = api.s.pendingTracker.TrackPendingTransaction(
|
2023-08-01 18:50:30 +00:00
|
|
|
wcommon.ChainID(chainID),
|
|
|
|
tx.Hash(),
|
|
|
|
common.Address(txArgs.From),
|
2024-03-14 08:39:06 +00:00
|
|
|
common.HexToAddress(contractAddress),
|
2023-08-01 18:50:30 +00:00
|
|
|
transactions.BurnCommunityToken,
|
2024-03-14 08:39:06 +00:00
|
|
|
transactions.Keep,
|
|
|
|
"",
|
2023-08-01 18:50:30 +00:00
|
|
|
)
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("TrackPendingTransaction error", zap.Error(err))
|
2023-08-01 18:50:30 +00:00
|
|
|
return "", err
|
|
|
|
}
|
2023-07-18 13:32:31 +00:00
|
|
|
|
2023-06-02 08:07:00 +00:00
|
|
|
return tx.Hash().Hex(), nil
|
|
|
|
}
|
|
|
|
|
2023-08-29 13:17:37 +00:00
|
|
|
// 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) {
|
2023-07-05 17:35:22 +00:00
|
|
|
return api.s.GetSignerPubKey(ctx, chainID, contractAddress)
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Gets signer public key directly from deployer contract
|
|
|
|
func (api *API) SafeGetSignerPubKey(ctx context.Context, chainID uint64, communityID string) (string, error) {
|
2023-07-05 17:35:22 +00:00
|
|
|
return api.s.SafeGetSignerPubKey(ctx, chainID, communityID)
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Gets owner token contract address from deployer contract
|
|
|
|
func (api *API) SafeGetOwnerTokenAddress(ctx context.Context, chainID uint64, communityID string) (string, error) {
|
2023-07-05 17:35:22 +00:00
|
|
|
return api.s.SafeGetOwnerTokenAddress(ctx, chainID, communityID)
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (api *API) SetSignerPubKey(ctx context.Context, chainID uint64, contractAddress string, txArgs transactions.SendTxArgs, password string, newSignerPubKey string) (string, error) {
|
2023-07-05 17:35:22 +00:00
|
|
|
return api.s.SetSignerPubKey(ctx, chainID, contractAddress, txArgs, password, newSignerPubKey)
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|
|
|
|
|
2023-10-13 08:08:40 +00:00
|
|
|
func (api *API) OwnerTokenOwnerAddress(ctx context.Context, chainID uint64, contractAddress string) (string, error) {
|
|
|
|
callOpts := &bind.CallOpts{Context: ctx, Pending: false}
|
|
|
|
contractInst, err := api.NewOwnerTokenInstance(chainID, contractAddress)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
ownerAddress, err := contractInst.OwnerOf(callOpts, big.NewInt(0))
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return ownerAddress.Hex(), nil
|
2023-08-29 13:17:37 +00:00
|
|
|
}
|