github.com/0chain/gosdk@v1.17.11/zcncore/wallet_base.go (about)

     1  package zcncore
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"fmt"
     8  	"math"
     9  	"net/http"
    10  	"net/url"
    11  	"strconv"
    12  	"strings"
    13  	"sync"
    14  	"time"
    15  
    16  	stdErrors "errors"
    17  
    18  	"github.com/0chain/errors"
    19  	"github.com/0chain/gosdk/core/common"
    20  	"github.com/0chain/gosdk/core/conf"
    21  	"github.com/0chain/gosdk/core/logger"
    22  	"github.com/0chain/gosdk/core/tokenrate"
    23  	"github.com/0chain/gosdk/core/util"
    24  	"github.com/0chain/gosdk/core/version"
    25  	"github.com/0chain/gosdk/core/zcncrypto"
    26  	"github.com/0chain/gosdk/zboxcore/encryption"
    27  	"github.com/0chain/gosdk/zboxcore/zboxutil"
    28  	openssl "github.com/Luzifer/go-openssl/v3"
    29  	"gopkg.in/natefinch/lumberjack.v2"
    30  )
    31  
    32  const (
    33  	GET_CLIENT                       = `/v1/client/get`
    34  	PUT_TRANSACTION                  = `/v1/transaction/put`
    35  	TXN_VERIFY_URL                   = `/v1/transaction/get/confirmation?hash=`
    36  	GET_BLOCK_INFO                   = `/v1/block/get?`
    37  	GET_MAGIC_BLOCK_INFO             = `/v1/block/magic/get?`
    38  	GET_LATEST_FINALIZED             = `/v1/block/get/latest_finalized`
    39  	GET_LATEST_FINALIZED_MAGIC_BLOCK = `/v1/block/get/latest_finalized_magic_block`
    40  	GET_FEE_STATS                    = `/v1/block/get/fee_stats`
    41  	GET_CHAIN_STATS                  = `/v1/chain/get/stats`
    42  	// vesting SC
    43  
    44  	VESTINGSC_PFX = `/v1/screst/` + VestingSmartContractAddress
    45  
    46  	GET_VESTING_CONFIG       = VESTINGSC_PFX + `/vesting-config`
    47  	GET_VESTING_POOL_INFO    = VESTINGSC_PFX + `/getPoolInfo`
    48  	GET_VESTING_CLIENT_POOLS = VESTINGSC_PFX + `/getClientPools`
    49  
    50  	// faucet sc
    51  
    52  	FAUCETSC_PFX        = `/v1/screst/` + FaucetSmartContractAddress
    53  	GET_FAUCETSC_CONFIG = FAUCETSC_PFX + `/faucet-config`
    54  
    55  	// zcn sc
    56  	ZCNSC_PFX                      = `/v1/screst/` + ZCNSCSmartContractAddress
    57  	GET_MINT_NONCE                 = ZCNSC_PFX + `/v1/mint_nonce`
    58  	GET_NOT_PROCESSED_BURN_TICKETS = ZCNSC_PFX + `/v1/not_processed_burn_tickets`
    59  	GET_AUTHORIZER                 = ZCNSC_PFX + `/getAuthorizer`
    60  
    61  	// miner SC
    62  
    63  	MINERSC_PFX          = `/v1/screst/` + MinerSmartContractAddress
    64  	GET_MINERSC_NODE     = MINERSC_PFX + "/nodeStat"
    65  	GET_MINERSC_POOL     = MINERSC_PFX + "/nodePoolStat"
    66  	GET_MINERSC_CONFIG   = MINERSC_PFX + "/configs"
    67  	GET_MINERSC_GLOBALS  = MINERSC_PFX + "/globalSettings"
    68  	GET_MINERSC_USER     = MINERSC_PFX + "/getUserPools"
    69  	GET_MINERSC_MINERS   = MINERSC_PFX + "/getMinerList"
    70  	GET_MINERSC_SHARDERS = MINERSC_PFX + "/getSharderList"
    71  	GET_MINERSC_EVENTS   = MINERSC_PFX + "/getEvents"
    72  
    73  	// storage SC
    74  
    75  	STORAGESC_PFX = "/v1/screst/" + StorageSmartContractAddress
    76  
    77  	STORAGESC_GET_SC_CONFIG            = STORAGESC_PFX + "/storage-config"
    78  	STORAGESC_GET_CHALLENGE_POOL_INFO  = STORAGESC_PFX + "/getChallengePoolStat"
    79  	STORAGESC_GET_ALLOCATION           = STORAGESC_PFX + "/allocation"
    80  	STORAGESC_GET_ALLOCATIONS          = STORAGESC_PFX + "/allocations"
    81  	STORAGESC_GET_READ_POOL_INFO       = STORAGESC_PFX + "/getReadPoolStat"
    82  	STORAGESC_GET_STAKE_POOL_INFO      = STORAGESC_PFX + "/getStakePoolStat"
    83  	STORAGESC_GET_STAKE_POOL_USER_INFO = STORAGESC_PFX + "/getUserStakePoolStat"
    84  	STORAGESC_GET_USER_LOCKED_TOTAL    = STORAGESC_PFX + "/getUserLockedTotal"
    85  	STORAGESC_GET_BLOBBERS             = STORAGESC_PFX + "/getblobbers"
    86  	STORAGESC_GET_BLOBBER              = STORAGESC_PFX + "/getBlobber"
    87  	STORAGESC_GET_VALIDATOR            = STORAGESC_PFX + "/get_validator"
    88  	STORAGESC_GET_TRANSACTIONS         = STORAGESC_PFX + "/transactions"
    89  
    90  	STORAGE_GET_SNAPSHOT            = STORAGESC_PFX + "/replicate-snapshots"
    91  	STORAGE_GET_BLOBBER_SNAPSHOT    = STORAGESC_PFX + "/replicate-blobber-aggregates"
    92  	STORAGE_GET_MINER_SNAPSHOT      = STORAGESC_PFX + "/replicate-miner-aggregates"
    93  	STORAGE_GET_SHARDER_SNAPSHOT    = STORAGESC_PFX + "/replicate-sharder-aggregates"
    94  	STORAGE_GET_AUTHORIZER_SNAPSHOT = STORAGESC_PFX + "/replicate-authorizer-aggregates"
    95  	STORAGE_GET_VALIDATOR_SNAPSHOT  = STORAGESC_PFX + "/replicate-validator-aggregates"
    96  	STORAGE_GET_USER_SNAPSHOT       = STORAGESC_PFX + "/replicate-user-aggregates"
    97  )
    98  
    99  const (
   100  	StorageSmartContractAddress  = `6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7`
   101  	VestingSmartContractAddress  = `2bba5b05949ea59c80aed3ac3474d7379d3be737e8eb5a968c52295e48333ead`
   102  	FaucetSmartContractAddress   = `6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d3`
   103  	MultiSigSmartContractAddress = `27b5ef7120252b79f9dd9c05505dd28f328c80f6863ee446daede08a84d651a7`
   104  	MinerSmartContractAddress    = `6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d9`
   105  	ZCNSCSmartContractAddress    = `6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712e0`
   106  	MultiSigRegisterFuncName     = "register"
   107  	MultiSigVoteFuncName         = "vote"
   108  )
   109  
   110  // In percentage
   111  const consensusThresh = 25
   112  
   113  const (
   114  	defaultMinSubmit               = int(10)
   115  	defaultMinConfirmation         = int(10)
   116  	defaultConfirmationChainLength = int(3)
   117  	defaultTxnExpirationSeconds    = 60
   118  	defaultWaitSeconds             = 3 * time.Second
   119  )
   120  
   121  const (
   122  	StatusSuccess      int = 0
   123  	StatusNetworkError int = 1
   124  	// TODO: Change to specific error
   125  	StatusError            int = 2
   126  	StatusRejectedByUser   int = 3
   127  	StatusInvalidSignature int = 4
   128  	StatusAuthError        int = 5
   129  	StatusAuthVerifyFailed int = 6
   130  	StatusAuthTimeout      int = 7
   131  	StatusUnknown          int = -1
   132  )
   133  
   134  var defaultLogLevel = logger.DEBUG
   135  var logging logger.Logger
   136  
   137  // GetLogger returns the logger instance
   138  func GetLogger() *logger.Logger {
   139  	return &logging
   140  }
   141  
   142  // CloseLog closes log file
   143  func CloseLog() {
   144  	logging.Close()
   145  }
   146  
   147  const TOKEN_UNIT int64 = 1e10
   148  
   149  const (
   150  	OpGetTokenLockConfig int = iota
   151  	OpGetLockedTokens
   152  	OpGetUserPools
   153  	OpGetUserPoolDetail
   154  	OpGetNotProcessedBurnTickets
   155  	OpGetMintNonce
   156  	// storage SC ops
   157  	// OpStorageSCGetConfig Get global storage SC config
   158  	OpStorageSCGetConfig
   159  
   160  	// OpStorageSCGetChallengePoolInfo Get challenge pool info
   161  	OpStorageSCGetChallengePoolInfo
   162  
   163  	// OpStorageSCGetAllocation Get allocation info
   164  	OpStorageSCGetAllocation
   165  
   166  	// OpStorageSCGetAllocations Get all allocations
   167  	OpStorageSCGetAllocations
   168  
   169  	// OpStorageSCGetReadPoolInfo Get read pool info
   170  	OpStorageSCGetReadPoolInfo
   171  
   172  	// OpStorageSCGetStakePoolInfo Get stake pool info
   173  	OpStorageSCGetStakePoolInfo
   174  
   175  	// OpStorageSCGetStakePoolUserInfo Get blobbers
   176  	OpStorageSCGetBlobbers
   177  
   178  	// OpStorageSCGetBlobber Get blobber information
   179  	OpStorageSCGetBlobber
   180  
   181  	// OpStorageSCGetValidator Get transaction info
   182  	OpStorageSCGetTransactions
   183  
   184  	// OpStorageSCGetSnapshots Get global snapshots
   185  	OpStorageSCGetSnapshots
   186  
   187  	// OpStorageSCGetBlobberSnapshots Get blobber snapshots
   188  	OpStorageSCGetBlobberSnapshots
   189  
   190  	// OpStorageSCGetMinerSnapshots Get miner snapshots
   191  	OpStorageSCGetMinerSnapshots
   192  
   193  	// OpStorageSCGetSharderSnapshots Get sharder snapshots
   194  	OpStorageSCGetSharderSnapshots
   195  
   196  	// OpStorageSCGetAuthorizerSnapshots Get authorizer snapshots
   197  	OpStorageSCGetAuthorizerSnapshots
   198  
   199  	// OpStorageSCGetValidatorSnapshots Get validator snapshots
   200  	OpStorageSCGetValidatorSnapshots
   201  
   202  	// OpStorageSCGetUserSnapshots Get user snapshots
   203  	OpStorageSCGetUserSnapshots
   204  
   205  	// OpStorageSCGetUserLockedTotal Get global configuration
   206  	OpZCNSCGetGlobalConfig
   207  
   208  	// OpZCNSCGetMintNonce Get authorizer information
   209  	OpZCNSCGetAuthorizer
   210  
   211  	// OpZCNSCGetAuthorizerNodes Get authorizer nodes
   212  	OpZCNSCGetAuthorizerNodes
   213  )
   214  
   215  // WalletCallback needs to be implemented for wallet creation.
   216  type WalletCallback interface {
   217  	OnWalletCreateComplete(status int, wallet string, err string)
   218  }
   219  
   220  // GetBalanceCallback needs to be implemented by the caller of GetBalance() to get the status
   221  type GetBalanceCallback interface {
   222  	OnBalanceAvailable(status int, value int64, info string)
   223  }
   224  
   225  // BurnTicket represents the burn ticket of native ZCN tokens used by the bridge protocol to mint ERC20 tokens
   226  type BurnTicket struct {
   227  	Hash   string `json:"hash"`
   228  	Amount int64  `json:"amount"`
   229  	Nonce  int64  `json:"nonce"`
   230  }
   231  
   232  // GetNonceCallback needs to be implemented by the caller of GetNonce() to get the status
   233  type GetNonceCallback interface {
   234  	OnNonceAvailable(status int, nonce int64, info string)
   235  }
   236  
   237  type GetNonceCallbackStub struct {
   238  	status int
   239  	nonce  int64
   240  	info   string
   241  }
   242  
   243  func (g *GetNonceCallbackStub) OnNonceAvailable(status int, nonce int64, info string) {
   244  	g.status = status
   245  	g.nonce = nonce
   246  	g.info = info
   247  }
   248  
   249  // GetInfoCallback represents the functions that will be called when the response of a GET request to the sharders is available
   250  type GetInfoCallback interface {
   251  	// OnInfoAvailable will be called when GetLockTokenConfig is complete
   252  	// if status == StatusSuccess then info is valid
   253  	// is status != StatusSuccess then err will give the reason
   254  	OnInfoAvailable(op int, status int, info string, err string)
   255  }
   256  
   257  // AuthCallback needs to be implemented by the caller SetupAuth()
   258  type AuthCallback interface {
   259  	// This call back gives the status of the Two factor authenticator(zauth) setup.
   260  	OnSetupComplete(status int, err string)
   261  }
   262  
   263  // Singleton
   264  var _config localConfig
   265  var miners []string
   266  var mGuard sync.Mutex
   267  
   268  func init() {
   269  	logging.Init(defaultLogLevel, "0chain-core-sdk")
   270  }
   271  
   272  func GetStableMiners() []string {
   273  	mGuard.Lock()
   274  	defer mGuard.Unlock()
   275  	if len(miners) == 0 {
   276  		miners = util.GetRandom(_config.chain.Miners, getMinMinersSubmit())
   277  	}
   278  
   279  	return miners
   280  }
   281  func ResetStableMiners() {
   282  	mGuard.Lock()
   283  	defer mGuard.Unlock()
   284  	miners = util.GetRandom(_config.chain.Miners, getMinMinersSubmit())
   285  }
   286  
   287  func checkSdkInit() error {
   288  	if !_config.isConfigured || len(_config.chain.Miners) < 1 || len(_config.chain.Sharders) < 1 {
   289  		return errors.New("", "SDK not initialized")
   290  	}
   291  	return nil
   292  }
   293  func checkWalletConfig() error {
   294  	if !_config.isValidWallet || _config.wallet.ClientID == "" {
   295  		logging.Error("wallet info not found. returning error.")
   296  		return errors.New("", "wallet info not found. set wallet info")
   297  	}
   298  	return nil
   299  }
   300  func CheckConfig() error {
   301  
   302  	err := checkSdkInit()
   303  	if err != nil {
   304  		return err
   305  	}
   306  	err = checkWalletConfig()
   307  	if err != nil {
   308  		return err
   309  	}
   310  	return nil
   311  }
   312  
   313  func assertConfig() {
   314  	if _config.chain.MinSubmit <= 0 {
   315  		_config.chain.MinSubmit = defaultMinSubmit
   316  	}
   317  	if _config.chain.MinConfirmation <= 0 {
   318  		_config.chain.MinConfirmation = defaultMinConfirmation
   319  	}
   320  	if _config.chain.ConfirmationChainLength <= 0 {
   321  		_config.chain.ConfirmationChainLength = defaultConfirmationChainLength
   322  	}
   323  }
   324  func getMinMinersSubmit() int {
   325  	minMiners := util.MaxInt(calculateMinRequired(float64(_config.chain.MinSubmit), float64(len(_config.chain.Miners))/100), 1)
   326  	logging.Info("Minimum miners used for submit :", minMiners)
   327  	return minMiners
   328  }
   329  
   330  func GetMinShardersVerify() int {
   331  	return getMinShardersVerify()
   332  }
   333  
   334  func getMinShardersVerify() int {
   335  	minSharders := util.MaxInt(calculateMinRequired(float64(_config.chain.MinConfirmation), float64(len(Sharders.Healthy()))/100), 1)
   336  	logging.Info("Minimum sharders used for verify :", minSharders)
   337  	return minSharders
   338  }
   339  func getMinRequiredChainLength() int64 {
   340  	return int64(_config.chain.ConfirmationChainLength)
   341  }
   342  
   343  func calculateMinRequired(minRequired, percent float64) int {
   344  	return int(math.Ceil(minRequired * percent))
   345  }
   346  
   347  // GetVersion - returns version string
   348  func GetVersion() string {
   349  	return version.VERSIONSTR
   350  }
   351  
   352  // SetLogLevel set the log level.
   353  //   - lvl: 0 disabled; higher number (upto 4) more verbosity
   354  func SetLogLevel(lvl int) {
   355  	logging.SetLevel(lvl)
   356  }
   357  
   358  // SetLogFile - sets file path to write log
   359  //   - logFile: log file path
   360  //   - verbose: true - console output; false - no console output
   361  func SetLogFile(logFile string, verbose bool) {
   362  	ioWriter := &lumberjack.Logger{
   363  		Filename:   logFile,
   364  		MaxSize:    100, // MB
   365  		MaxBackups: 5,   // number of backups
   366  		MaxAge:     28,  //days
   367  		LocalTime:  false,
   368  		Compress:   false, // disabled by default
   369  	}
   370  	logging.SetLogFile(ioWriter, verbose)
   371  	logging.Info("******* Wallet SDK Version:", version.VERSIONSTR, " ******* (SetLogFile)")
   372  }
   373  
   374  // Init initialize the SDK with miner, sharder and signature scheme provided in configuration provided in JSON format
   375  // # Inputs
   376  //   - chainConfigJSON: json format of zcn config
   377  //     {
   378  //     "block_worker": "https://dev.0chain.net/dns",
   379  //     "signature_scheme": "bls0chain",
   380  //     "min_submit": 50,
   381  //     "min_confirmation": 50,
   382  //     "confirmation_chain_length": 3,
   383  //     "max_txn_query": 5,
   384  //     "query_sleep_time": 5,
   385  //     "preferred_blobbers": ["https://dev.0chain.net/blobber02","https://dev.0chain.net/blobber03"],
   386  //     "chain_id":"0afc093ffb509f059c55478bc1a60351cef7b4e9c008a53a6cc8241ca8617dfe",
   387  //     "ethereum_node":"https://ropsten.infura.io/v3/xxxxxxxxxxxxxxx",
   388  //     "zbox_host":"https://0box.dev.0chain.net",
   389  //     "zbox_app_type":"vult",
   390  //     "sharder_consensous": 2,
   391  //     }
   392  func Init(chainConfigJSON string) error {
   393  	err := json.Unmarshal([]byte(chainConfigJSON), &_config.chain)
   394  	if err == nil {
   395  		// Check signature scheme is supported
   396  		if _config.chain.SignatureScheme != "ed25519" && _config.chain.SignatureScheme != "bls0chain" {
   397  			return errors.New("", "invalid/unsupported signature scheme")
   398  		}
   399  
   400  		err = UpdateNetworkDetails()
   401  		if err != nil {
   402  			return err
   403  		}
   404  
   405  		go updateNetworkDetailsWorker(context.Background())
   406  
   407  		assertConfig()
   408  		_config.isConfigured = true
   409  
   410  		cfg := &conf.Config{
   411  			BlockWorker:             _config.chain.BlockWorker,
   412  			MinSubmit:               _config.chain.MinSubmit,
   413  			MinConfirmation:         _config.chain.MinConfirmation,
   414  			ConfirmationChainLength: _config.chain.ConfirmationChainLength,
   415  			SignatureScheme:         _config.chain.SignatureScheme,
   416  			ChainID:                 _config.chain.ChainID,
   417  			EthereumNode:            _config.chain.EthNode,
   418  			SharderConsensous:       _config.chain.SharderConsensous,
   419  		}
   420  
   421  		conf.InitClientConfig(cfg)
   422  	}
   423  	logging.Info("0chain: test logging")
   424  	logging.Info("******* Wallet SDK Version:", version.VERSIONSTR, " ******* (Init) Test")
   425  	return err
   426  }
   427  
   428  // InitSignatureScheme initializes signature scheme only.
   429  //   - scheme: signature scheme
   430  func InitSignatureScheme(scheme string) {
   431  	_config.chain.SignatureScheme = scheme
   432  }
   433  
   434  // CreateWalletOffline creates the wallet for the config signature scheme.
   435  func CreateWalletOffline() (string, error) {
   436  	sigScheme := zcncrypto.NewSignatureScheme(_config.chain.SignatureScheme)
   437  	wallet, err := sigScheme.GenerateKeys()
   438  	if err != nil {
   439  		return "", errors.Wrap(err, "failed to generate keys")
   440  	}
   441  	w, err := wallet.Marshal()
   442  	if err != nil {
   443  		return "", errors.Wrap(err, "wallet encoding failed")
   444  	}
   445  	return w, nil
   446  }
   447  
   448  // RecoverOfflineWallet recovers the previously generated wallet using the mnemonic.
   449  //   - mnemonic: mnemonics to recover
   450  func RecoverOfflineWallet(mnemonic string) (string, error) {
   451  	if !zcncrypto.IsMnemonicValid(mnemonic) {
   452  		return "", errors.New("", "Invalid mnemonic")
   453  	}
   454  
   455  	sigScheme := zcncrypto.NewSignatureScheme(_config.chain.SignatureScheme)
   456  	wallet, err := sigScheme.RecoverKeys(mnemonic)
   457  	if err != nil {
   458  		return "", err
   459  	}
   460  
   461  	walletString, err := wallet.Marshal()
   462  	if err != nil {
   463  		return "", err
   464  	}
   465  
   466  	return walletString, nil
   467  }
   468  
   469  // RecoverWallet recovers the previously generated wallet using the mnemonic.
   470  // It also registers the wallet again to block chain.
   471  func RecoverWallet(mnemonic string, statusCb WalletCallback) error {
   472  	if !zcncrypto.IsMnemonicValid(mnemonic) {
   473  		return errors.New("", "Invalid mnemonic")
   474  	}
   475  	go func() {
   476  		sigScheme := zcncrypto.NewSignatureScheme(_config.chain.SignatureScheme)
   477  		_, err := sigScheme.RecoverKeys(mnemonic)
   478  		if err != nil {
   479  			statusCb.OnWalletCreateComplete(StatusError, "", err.Error())
   480  			return
   481  		}
   482  	}()
   483  	return nil
   484  }
   485  
   486  // Split keys from the primary master key
   487  func SplitKeys(privateKey string, numSplits int) (string, error) {
   488  	w, err := SplitKeysWallet(privateKey, numSplits)
   489  	if err != nil {
   490  		return "", errors.Wrap(err, "split key failed.")
   491  	}
   492  	wStr, err := w.Marshal()
   493  	if err != nil {
   494  		return "", errors.Wrap(err, "wallet encoding failed.")
   495  	}
   496  	return wStr, nil
   497  }
   498  
   499  func SplitKeysWallet(privateKey string, numSplits int) (*zcncrypto.Wallet, error) {
   500  	if _config.chain.SignatureScheme != "bls0chain" {
   501  		return nil, errors.New("", "signature key doesn't support split key")
   502  	}
   503  	sigScheme := zcncrypto.NewSignatureScheme(_config.chain.SignatureScheme)
   504  	err := sigScheme.SetPrivateKey(privateKey)
   505  	if err != nil {
   506  		return nil, errors.Wrap(err, "set private key failed")
   507  	}
   508  	w, err := sigScheme.SplitKeys(numSplits)
   509  	if err != nil {
   510  		return nil, errors.Wrap(err, "split key failed.")
   511  	}
   512  
   513  	w.IsSplit = true
   514  
   515  	return w, nil
   516  }
   517  
   518  type GetClientResponse struct {
   519  	ID           string `json:"id"`
   520  	Version      string `json:"version"`
   521  	CreationDate int    `json:"creation_date"`
   522  	PublicKey    string `json:"public_key"`
   523  }
   524  
   525  func GetClientDetails(clientID string) (*GetClientResponse, error) {
   526  	minerurl := util.GetRandom(_config.chain.Miners, 1)[0]
   527  	url := minerurl + GET_CLIENT
   528  	url = fmt.Sprintf("%v?id=%v", url, clientID)
   529  	req, err := util.NewHTTPGetRequest(url)
   530  	if err != nil {
   531  		logging.Error(minerurl, "new get request failed. ", err.Error())
   532  		return nil, err
   533  	}
   534  	res, err := req.Get()
   535  	if err != nil {
   536  		logging.Error(minerurl, "send error. ", err.Error())
   537  		return nil, err
   538  	}
   539  
   540  	var clientDetails GetClientResponse
   541  	err = json.Unmarshal([]byte(res.Body), &clientDetails)
   542  	if err != nil {
   543  		return nil, err
   544  	}
   545  
   546  	return &clientDetails, nil
   547  }
   548  
   549  // IsMnemonicValid is a utility function to check the mnemonic valid
   550  //   - mnemonic: mnemonics to check
   551  func IsMnemonicValid(mnemonic string) bool {
   552  	return zcncrypto.IsMnemonicValid(mnemonic)
   553  }
   554  
   555  // SetWallet should be set before any transaction or client specific APIs
   556  // splitKeyWallet parameter is valid only if SignatureScheme is "BLS0Chain"
   557  func SetWallet(w zcncrypto.Wallet, splitKeyWallet bool) error {
   558  	_config.wallet = w
   559  
   560  	if _config.chain.SignatureScheme == "bls0chain" {
   561  		_config.isSplitWallet = splitKeyWallet
   562  	}
   563  	_config.isValidWallet = true
   564  
   565  	return nil
   566  }
   567  
   568  func GetWalletRaw() zcncrypto.Wallet {
   569  	return _config.wallet
   570  }
   571  
   572  // SetWalletInfo should be set before any transaction or client specific APIs.
   573  // "splitKeyWallet" parameter is valid only if SignatureScheme is "BLS0Chain"
   574  //   - jsonWallet: json format of wallet
   575  //   - splitKeyWallet: if wallet keys is split
   576  func SetWalletInfo(jsonWallet string, splitKeyWallet bool) error {
   577  	err := json.Unmarshal([]byte(jsonWallet), &_config.wallet)
   578  	if err != nil {
   579  		return err
   580  	}
   581  
   582  	if _config.chain.SignatureScheme == "bls0chain" {
   583  		_config.isSplitWallet = splitKeyWallet
   584  	}
   585  	_config.isValidWallet = true
   586  
   587  	return nil
   588  }
   589  
   590  // SetAuthUrl will be called by app to set zauth URL to SDK.
   591  // # Inputs
   592  //   - url: the url of zAuth server
   593  func SetAuthUrl(url string) error {
   594  	if !_config.isSplitWallet {
   595  		return errors.New("", "wallet type is not split key")
   596  	}
   597  	if url == "" {
   598  		return errors.New("", "invalid auth url")
   599  	}
   600  	_config.authUrl = strings.TrimRight(url, "/")
   601  	return nil
   602  }
   603  
   604  func getWalletBalance(clientId string) (common.Balance, int64, error) {
   605  	err := checkSdkInit()
   606  	if err != nil {
   607  		return 0, 0, err
   608  	}
   609  
   610  	cb := &walletCallback{}
   611  	cb.Add(1)
   612  
   613  	go func() {
   614  		value, info, err := getBalanceFromSharders(clientId)
   615  		if err != nil && strings.TrimSpace(info) != `{"error":"value not present"}` {
   616  			cb.OnBalanceAvailable(StatusError, value, info)
   617  			cb.err = err
   618  			return
   619  		}
   620  		cb.OnBalanceAvailable(StatusSuccess, value, info)
   621  	}()
   622  
   623  	cb.Wait()
   624  
   625  	var clientState struct {
   626  		Nonce int64 `json:"nonce"`
   627  	}
   628  	err = json.Unmarshal([]byte(cb.info), &clientState)
   629  	if err != nil {
   630  		return 0, 0, err
   631  	}
   632  
   633  	return cb.balance, clientState.Nonce, cb.err
   634  }
   635  
   636  // GetBalance retrieve wallet balance from sharders
   637  //   - cb: info callback instance, carries the response of the GET request to the sharders
   638  func GetBalance(cb GetBalanceCallback) error {
   639  	err := CheckConfig()
   640  	if err != nil {
   641  		return err
   642  	}
   643  	go func() {
   644  		value, info, err := getBalanceFromSharders(_config.wallet.ClientID)
   645  		if err != nil {
   646  			logging.Error(err)
   647  			cb.OnBalanceAvailable(StatusError, 0, info)
   648  			return
   649  		}
   650  		cb.OnBalanceAvailable(StatusSuccess, value, info)
   651  	}()
   652  	return nil
   653  }
   654  
   655  // GetMintNonce retrieve the client's latest mint nonce from sharders
   656  //   - cb: info callback instance, carries the response of the GET request to the sharders
   657  func GetMintNonce(cb GetInfoCallback) error {
   658  	err := CheckConfig()
   659  	if err != nil {
   660  		return err
   661  	}
   662  
   663  	go GetInfoFromSharders(withParams(GET_MINT_NONCE, Params{
   664  		"client_id": _config.wallet.ClientID,
   665  	}), OpGetMintNonce, cb)
   666  	return nil
   667  }
   668  
   669  // GetNotProcessedZCNBurnTickets retrieve burn tickets that are not compensated by minting
   670  //   - ethereumAddress: ethereum address for the issuer of the burn tickets
   671  //   - startNonce: start nonce for the burn tickets
   672  //   - cb: info callback instance, carries the response of the GET request to the sharders
   673  func GetNotProcessedZCNBurnTickets(ethereumAddress, startNonce string, cb GetInfoCallback) error {
   674  	err := CheckConfig()
   675  	if err != nil {
   676  		return err
   677  	}
   678  
   679  	go GetInfoFromSharders(withParams(GET_NOT_PROCESSED_BURN_TICKETS, Params{
   680  		"ethereum_address": ethereumAddress,
   681  		"nonce":            startNonce,
   682  	}), OpGetNotProcessedBurnTickets, cb)
   683  
   684  	return nil
   685  }
   686  
   687  // GetNonce retrieve wallet nonce from sharders
   688  //   - cb: info callback instance, carries the response of the GET request to the sharders
   689  func GetNonce(cb GetNonceCallback) error {
   690  	if cb == nil {
   691  		cb = &GetNonceCallbackStub{}
   692  	}
   693  
   694  	err := CheckConfig()
   695  	if err != nil {
   696  		return err
   697  	}
   698  
   699  	go func() {
   700  		value, info, err := getNonceFromSharders(_config.wallet.ClientID)
   701  		if err != nil {
   702  			logging.Error(err)
   703  			cb.OnNonceAvailable(StatusError, 0, info)
   704  			return
   705  		}
   706  
   707  		cb.OnNonceAvailable(StatusSuccess, value, info)
   708  	}()
   709  
   710  	return nil
   711  }
   712  
   713  // GetWalletBalance retrieve wallet nonce from sharders
   714  //   - clientID: client id
   715  func GetWalletNonce(clientID string) (int64, error) {
   716  	cb := &GetNonceCallbackStub{}
   717  
   718  	err := CheckConfig()
   719  	if err != nil {
   720  		return 0, err
   721  	}
   722  	wait := &sync.WaitGroup{}
   723  	wait.Add(1)
   724  	go func() {
   725  		defer wait.Done()
   726  		value, info, err := getNonceFromSharders(clientID)
   727  		if err != nil {
   728  			logging.Error(err)
   729  			cb.OnNonceAvailable(StatusError, 0, info)
   730  			return
   731  		}
   732  		cb.OnNonceAvailable(StatusSuccess, value, info)
   733  	}()
   734  
   735  	wait.Wait()
   736  
   737  	if cb.status == StatusSuccess {
   738  		return cb.nonce, nil
   739  	}
   740  
   741  	return 0, stdErrors.New(cb.info)
   742  }
   743  
   744  // GetBalanceWallet retreives wallet balance from sharders
   745  //   - walletStr: wallet string
   746  //   - cb: info callback instance, carries the response of the GET request to the sharders
   747  func GetBalanceWallet(walletStr string, cb GetBalanceCallback) error {
   748  	w, err := getWallet(walletStr)
   749  	if err != nil {
   750  		fmt.Printf("Error while parsing the wallet. %v\n", err)
   751  		return err
   752  	}
   753  
   754  	go func() {
   755  		value, info, err := getBalanceFromSharders(w.ClientID)
   756  		if err != nil {
   757  			logging.Error(err)
   758  			cb.OnBalanceAvailable(StatusError, 0, info)
   759  			return
   760  		}
   761  		cb.OnBalanceAvailable(StatusSuccess, value, info)
   762  	}()
   763  	return nil
   764  }
   765  
   766  func getBalanceFromSharders(clientID string) (int64, string, error) {
   767  	return Sharders.GetBalanceFieldFromSharders(clientID, "balance")
   768  }
   769  
   770  func getNonceFromSharders(clientID string) (int64, string, error) {
   771  	return Sharders.GetBalanceFieldFromSharders(clientID, "nonce")
   772  }
   773  
   774  // ConvertToToken converts the SAS tokens to ZCN tokens
   775  //   - token: SAS tokens amount
   776  func ConvertToToken(token int64) float64 {
   777  	return float64(token) / float64(common.TokenUnit)
   778  }
   779  
   780  // ConvertTokenToUSD converts the ZCN tokens to USD amount
   781  //   - token: ZCN tokens amount
   782  func ConvertTokenToUSD(token float64) (float64, error) {
   783  	zcnRate, err := getTokenUSDRate()
   784  	if err != nil {
   785  		return 0, err
   786  	}
   787  	return token * zcnRate, nil
   788  }
   789  
   790  // ConvertUSDToToken converts the USD amount to ZCN tokens
   791  //   - usd: USD amount
   792  func ConvertUSDToToken(usd float64) (float64, error) {
   793  	zcnRate, err := getTokenUSDRate()
   794  	if err != nil {
   795  		return 0, err
   796  	}
   797  	return usd * (1 / zcnRate), nil
   798  }
   799  
   800  func getTokenUSDRate() (float64, error) {
   801  	return tokenrate.GetUSD(context.TODO(), "zcn")
   802  }
   803  
   804  // getWallet get a wallet object from a wallet string
   805  func getWallet(walletStr string) (*zcncrypto.Wallet, error) {
   806  	var w zcncrypto.Wallet
   807  	err := json.Unmarshal([]byte(walletStr), &w)
   808  	if err != nil {
   809  		fmt.Printf("error while parsing wallet string.\n%v\n", err)
   810  		return nil, err
   811  	}
   812  
   813  	return &w, nil
   814  }
   815  
   816  // GetWalletClientID extract wallet client id from wallet string
   817  //   - walletStr: wallet string to get client id
   818  func GetWalletClientID(walletStr string) (string, error) {
   819  	w, err := getWallet(walletStr)
   820  	if err != nil {
   821  		return "", err
   822  	}
   823  	return w.ClientID, nil
   824  }
   825  
   826  // GetZcnUSDInfo returns USD value for ZCN token by tokenrate
   827  func GetZcnUSDInfo() (float64, error) {
   828  	return tokenrate.GetUSD(context.TODO(), "zcn")
   829  }
   830  
   831  // SetupAuth prepare auth app with clientid, key and a set of public, private key and local publickey
   832  // which is running on PC/Mac.
   833  func SetupAuth(authHost, clientID, clientKey, publicKey, privateKey, localPublicKey string, cb AuthCallback) error {
   834  	go func() {
   835  		authHost = strings.TrimRight(authHost, "/")
   836  		data := map[string]string{"client_id": clientID, "client_key": clientKey, "public_key": publicKey, "private_key": privateKey, "peer_public_key": localPublicKey}
   837  		req, err := util.NewHTTPPostRequest(authHost+"/setup", data)
   838  		if err != nil {
   839  			logging.Error("new post request failed. ", err.Error())
   840  			return
   841  		}
   842  		res, err := req.Post()
   843  		if err != nil {
   844  			logging.Error(authHost+"send error. ", err.Error())
   845  		}
   846  		if res.StatusCode != http.StatusOK {
   847  			cb.OnSetupComplete(StatusError, res.Body)
   848  			return
   849  		}
   850  		cb.OnSetupComplete(StatusSuccess, "")
   851  	}()
   852  	return nil
   853  }
   854  
   855  // GetIdForUrl retrieve the ID of the network node (miner/sharder) given its url.
   856  //   - url: url of the node.
   857  func GetIdForUrl(url string) string {
   858  	url = strings.TrimRight(url, "/")
   859  	url = fmt.Sprintf("%v/_nh/whoami", url)
   860  	req, err := util.NewHTTPGetRequest(url)
   861  	if err != nil {
   862  		logging.Error(url, "new get request failed. ", err.Error())
   863  		return ""
   864  	}
   865  	res, err := req.Get()
   866  	if err != nil {
   867  		logging.Error(url, "get error. ", err.Error())
   868  		return ""
   869  	}
   870  
   871  	s := strings.Split(res.Body, ",")
   872  	if len(s) >= 3 {
   873  		return s[3]
   874  	}
   875  	return ""
   876  }
   877  
   878  //
   879  // vesting pool
   880  //
   881  
   882  type Params map[string]string
   883  
   884  func (p Params) Query() string {
   885  	if len(p) == 0 {
   886  		return ""
   887  	}
   888  	var params = make(url.Values)
   889  	for k, v := range p {
   890  		params[k] = []string{v}
   891  	}
   892  	return "?" + params.Encode()
   893  }
   894  
   895  //
   896  // miner SC
   897  //
   898  
   899  // GetMiners obtains list of all active miners.
   900  //   - cb: info callback instance, carries the response of the GET request to the sharders
   901  //   - limit: how many miners should be fetched
   902  //   - offset: how many miners should be skipped
   903  //   - active: retrieve only active miners
   904  //   - stakable: retreive only stakable miners
   905  func GetMiners(cb GetInfoCallback, limit, offset int, active bool, stakable bool) {
   906  	getMinersInternal(cb, active, stakable, limit, offset)
   907  }
   908  
   909  func getMinersInternal(cb GetInfoCallback, active, stakable bool, limit, offset int) {
   910  	if err := CheckConfig(); err != nil {
   911  		return
   912  	}
   913  
   914  	var url = withParams(GET_MINERSC_MINERS, Params{
   915  		"active":   strconv.FormatBool(active),
   916  		"stakable": strconv.FormatBool(stakable),
   917  		"offset":   strconv.FormatInt(int64(offset), 10),
   918  		"limit":    strconv.FormatInt(int64(limit), 10),
   919  	})
   920  
   921  	go GetInfoFromSharders(url, 0, cb)
   922  }
   923  
   924  // GetSharders obtains a list of sharders given the following parameters.
   925  //   - cb: info callback instance, carries the response of the GET request to the sharders
   926  //   - limit: how many sharders should be fetched
   927  //   - offset: how many sharders should be skipped
   928  //   - active: retrieve only active sharders
   929  //   - stakable: retrieve only sharders that can be staked
   930  func GetSharders(cb GetInfoCallback, limit, offset int, active, stakable bool) {
   931  	getShardersInternal(cb, active, stakable, limit, offset)
   932  }
   933  
   934  func getShardersInternal(cb GetInfoCallback, active, stakable bool, limit, offset int) {
   935  	if err := CheckConfig(); err != nil {
   936  		return
   937  	}
   938  
   939  	var url = withParams(GET_MINERSC_SHARDERS, Params{
   940  		"active":   strconv.FormatBool(active),
   941  		"stakable": strconv.FormatBool(stakable),
   942  		"offset":   strconv.FormatInt(int64(offset), 10),
   943  		"limit":    strconv.FormatInt(int64(limit), 10),
   944  	})
   945  
   946  	go GetInfoFromSharders(url, 0, cb)
   947  }
   948  
   949  func withParams(uri string, params Params) string {
   950  	return uri + params.Query()
   951  }
   952  
   953  // GetMinerSCNodeInfo get miner information from sharders
   954  //   - id: the id of miner
   955  //   - cb: info callback instance, carries the response of the GET request to the sharders
   956  func GetMinerSCNodeInfo(id string, cb GetInfoCallback) (err error) {
   957  
   958  	if err = CheckConfig(); err != nil {
   959  		return
   960  	}
   961  
   962  	go GetInfoFromSharders(withParams(GET_MINERSC_NODE, Params{
   963  		"id": id,
   964  	}), 0, cb)
   965  	return
   966  }
   967  
   968  // GetMinerSCNodePool get miner smart contract node pool
   969  //   - id: the id of miner
   970  //   - cb: info callback instance, carries the response of the GET request to the sharders
   971  func GetMinerSCNodePool(id string, cb GetInfoCallback) (err error) {
   972  	if err = CheckConfig(); err != nil {
   973  		return
   974  	}
   975  	go GetInfoFromSharders(withParams(GET_MINERSC_POOL, Params{
   976  		"id":      id,
   977  		"pool_id": _config.wallet.ClientID,
   978  	}), 0, cb)
   979  
   980  	return
   981  }
   982  
   983  // GetMinerSCUserInfo retrieve user stake pools for the providers related to the Miner SC (miners/sharders).
   984  //   - clientID: user's wallet id
   985  //   - cb: info callback instance, carries the response of the GET request to the sharders
   986  func GetMinerSCUserInfo(clientID string, cb GetInfoCallback) (err error) {
   987  	if err = CheckConfig(); err != nil {
   988  		return
   989  	}
   990  	if clientID == "" {
   991  		clientID = _config.wallet.ClientID
   992  	}
   993  	go GetInfoFromSharders(withParams(GET_MINERSC_USER, Params{
   994  		"client_id": clientID,
   995  	}), 0, cb)
   996  
   997  	return
   998  }
   999  
  1000  // GetMinerSCConfig get miner SC configuration
  1001  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1002  func GetMinerSCConfig(cb GetInfoCallback) (err error) {
  1003  	if err = CheckConfig(); err != nil {
  1004  		return
  1005  	}
  1006  	go GetInfoFromSharders(GET_MINERSC_CONFIG, 0, cb)
  1007  	return
  1008  }
  1009  
  1010  // GetMinerSCGlobals get miner SC globals
  1011  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1012  func GetMinerSCGlobals(cb GetInfoCallback) (err error) {
  1013  	if err = CheckConfig(); err != nil {
  1014  		return
  1015  	}
  1016  	go GetInfoFromSharders(GET_MINERSC_GLOBALS, 0, cb)
  1017  	return
  1018  }
  1019  
  1020  //
  1021  // Storage SC
  1022  //
  1023  
  1024  // GetStorageSCConfig obtains Storage SC configurations.
  1025  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1026  func GetStorageSCConfig(cb GetInfoCallback) (err error) {
  1027  	if err = CheckConfig(); err != nil {
  1028  		return
  1029  	}
  1030  	go GetInfoFromSharders(STORAGESC_GET_SC_CONFIG, OpStorageSCGetConfig, cb)
  1031  	return
  1032  }
  1033  
  1034  // GetChallengePoolInfo obtains challenge pool information for an allocation.
  1035  func GetChallengePoolInfo(allocID string, cb GetInfoCallback) (err error) {
  1036  	if err = CheckConfig(); err != nil {
  1037  		return
  1038  	}
  1039  	var url = withParams(STORAGESC_GET_CHALLENGE_POOL_INFO, Params{
  1040  		"allocation_id": allocID,
  1041  	})
  1042  	go GetInfoFromSharders(url, OpStorageSCGetChallengePoolInfo, cb)
  1043  	return
  1044  }
  1045  
  1046  // GetAllocation obtains allocation information.
  1047  func GetAllocation(allocID string, cb GetInfoCallback) (err error) {
  1048  	if err = CheckConfig(); err != nil {
  1049  		return
  1050  	}
  1051  	var url = withParams(STORAGESC_GET_ALLOCATION, Params{
  1052  		"allocation": allocID,
  1053  	})
  1054  	go GetInfoFromSharders(url, OpStorageSCGetAllocation, cb)
  1055  	return
  1056  }
  1057  
  1058  // GetAllocations obtains list of allocations of a user.
  1059  func GetAllocations(clientID string, cb GetInfoCallback) (err error) {
  1060  	if err = CheckConfig(); err != nil {
  1061  		return
  1062  	}
  1063  	if clientID == "" {
  1064  		clientID = _config.wallet.ClientID
  1065  	}
  1066  	var url = withParams(STORAGESC_GET_ALLOCATIONS, Params{
  1067  		"client": clientID,
  1068  	})
  1069  	go GetInfoFromSharders(url, OpStorageSCGetAllocations, cb)
  1070  	return
  1071  }
  1072  
  1073  // GetSnapshots obtains list of global snapshots, given an initial round and a limit.
  1074  // Global snapshots are historical records of some aggregate data related
  1075  // to the network (like total staked amount and total reward amount).
  1076  //   - round: round number to start fetching snapshots
  1077  //   - limit: how many snapshots should be fetched
  1078  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1079  func GetSnapshots(round int64, limit int64, cb GetInfoCallback) (err error) {
  1080  	if err = CheckConfig(); err != nil {
  1081  		return
  1082  	}
  1083  	var url = withParams(STORAGE_GET_SNAPSHOT, Params{
  1084  		"round": strconv.FormatInt(round, 10),
  1085  		"limit": strconv.FormatInt(limit, 10),
  1086  	})
  1087  	go GetInfoFromAnySharder(url, OpStorageSCGetSnapshots, cb)
  1088  	return
  1089  }
  1090  
  1091  // GetBlobberSnapshots obtains list of allocations of a blobber.
  1092  // Blobber snapshots are historical records of the blobber instance to track its change over time and serve graph requests,
  1093  // which are requests that need multiple data points, distributed over an interval of time, usually to plot them on a
  1094  // graph.
  1095  //   - round: round number
  1096  //   - limit: how many blobber snapshots should be fetched
  1097  //   - offset: how many blobber snapshots should be skipped
  1098  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1099  func GetBlobberSnapshots(round int64, limit int64, offset int64, cb GetInfoCallback) (err error) {
  1100  	if err = CheckConfig(); err != nil {
  1101  		return
  1102  	}
  1103  	var url = withParams(STORAGE_GET_BLOBBER_SNAPSHOT, Params{
  1104  		"round":  strconv.FormatInt(round, 10),
  1105  		"limit":  strconv.FormatInt(limit, 10),
  1106  		"offset": strconv.FormatInt(offset, 10),
  1107  	})
  1108  	go GetInfoFromAnySharder(url, OpStorageSCGetBlobberSnapshots, cb)
  1109  	return
  1110  }
  1111  
  1112  // GetMinerSnapshots obtains a list of miner snapshots starting from a specific round.
  1113  // Miner snapshots are historical records of the miner instance to track its change over time and serve graph requests,
  1114  // which are requests that need multiple data points, distributed over an interval of time, usually to plot them on a
  1115  // graph.
  1116  //   - round: round number to start fetching snapshots
  1117  //   - limit: how many miner snapshots should be fetched
  1118  //   - offset: how many miner snapshots should be skipped
  1119  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1120  func GetMinerSnapshots(round int64, limit int64, offset int64, cb GetInfoCallback) (err error) {
  1121  	if err = CheckConfig(); err != nil {
  1122  		return
  1123  	}
  1124  	var url = withParams(STORAGE_GET_MINER_SNAPSHOT, Params{
  1125  		"round":  strconv.FormatInt(round, 10),
  1126  		"limit":  strconv.FormatInt(limit, 10),
  1127  		"offset": strconv.FormatInt(offset, 10),
  1128  	})
  1129  	go GetInfoFromAnySharder(url, OpStorageSCGetMinerSnapshots, cb)
  1130  	return
  1131  }
  1132  
  1133  // GetSharderSnapshots obtains a list of sharder snapshots starting from a specific round.
  1134  // Sharder snapshots are historical records of the sharder instance to track its change over time and serve graph requests,
  1135  // which are requests that need multiple data points, distributed over an interval of time, usually to plot them on a
  1136  // graph.
  1137  //   - round: round number to start fetching snapshots
  1138  //   - limit: how many sharder snapshots should be fetched
  1139  //   - offset: how many sharder snapshots should be skipped
  1140  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1141  func GetSharderSnapshots(round int64, limit int64, offset int64, cb GetInfoCallback) (err error) {
  1142  	if err = CheckConfig(); err != nil {
  1143  		return
  1144  	}
  1145  	var url = withParams(STORAGE_GET_SHARDER_SNAPSHOT, Params{
  1146  		"round":  strconv.FormatInt(round, 10),
  1147  		"limit":  strconv.FormatInt(limit, 10),
  1148  		"offset": strconv.FormatInt(offset, 10),
  1149  	})
  1150  	go GetInfoFromAnySharder(url, OpStorageSCGetSharderSnapshots, cb)
  1151  	return
  1152  }
  1153  
  1154  // GetValidatorSnapshots obtains list of validator snapshots from the sharders.
  1155  // Validator snapshots are historical records of the validator instance to track its change over time and serve graph requests,
  1156  // which are requests that need multiple data points, distributed over an interval of time, usually to plot them on a
  1157  // graph.
  1158  //   - round: round number to start fetching snapshots
  1159  //   - limit: how many validator snapshots should be fetched
  1160  //   - offset: how many validator snapshots should be skipped
  1161  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1162  func GetValidatorSnapshots(round int64, limit int64, offset int64, cb GetInfoCallback) (err error) {
  1163  	if err = CheckConfig(); err != nil {
  1164  		return
  1165  	}
  1166  	var url = withParams(STORAGE_GET_VALIDATOR_SNAPSHOT, Params{
  1167  		"round":  strconv.FormatInt(round, 10),
  1168  		"limit":  strconv.FormatInt(limit, 10),
  1169  		"offset": strconv.FormatInt(offset, 10),
  1170  	})
  1171  	go GetInfoFromAnySharder(url, OpStorageSCGetValidatorSnapshots, cb)
  1172  	return
  1173  }
  1174  
  1175  // GetAuthorizerSnapshots obtains list of authorizers snapshots from the sharders.
  1176  // Authorizer snapshots are historical records of the authorizer instance to track its change over time and serve graph requests,
  1177  // which are requests that need multiple data points, distributed over an interval of time, usually to plot them on a
  1178  // graph.
  1179  //   - round: round number to start fetching snapshots
  1180  //   - limit: how many authorizer snapshots should be fetched
  1181  //   - offset: how many authorizer snapshots should be skipped
  1182  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1183  func GetAuthorizerSnapshots(round int64, limit int64, offset int64, cb GetInfoCallback) (err error) {
  1184  	if err = CheckConfig(); err != nil {
  1185  		return
  1186  	}
  1187  	var url = withParams(STORAGE_GET_AUTHORIZER_SNAPSHOT, Params{
  1188  		"round":  strconv.FormatInt(round, 10),
  1189  		"limit":  strconv.FormatInt(limit, 10),
  1190  		"offset": strconv.FormatInt(offset, 10),
  1191  	})
  1192  	go GetInfoFromAnySharder(url, OpStorageSCGetAuthorizerSnapshots, cb)
  1193  	return
  1194  }
  1195  
  1196  // GetUserSnapshots replicates user snapshots from the sharders
  1197  // User snapshots are historical records of the client data to track its change over time and serve graph requests,
  1198  // which are requests that need multiple data points, distributed over an interval of time, usually to plot them on a
  1199  // graph.
  1200  //   - round: round number to start fetching snapshots
  1201  //   - limit: how many user snapshots should be fetched
  1202  //   - offset: how many user snapshots should be skipped
  1203  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1204  func GetUserSnapshots(round int64, limit int64, offset int64, cb GetInfoCallback) (err error) {
  1205  	if err = CheckConfig(); err != nil {
  1206  		return
  1207  	}
  1208  	var url = withParams(STORAGE_GET_USER_SNAPSHOT, Params{
  1209  		"round":  strconv.FormatInt(round, 10),
  1210  		"limit":  strconv.FormatInt(limit, 10),
  1211  		"offset": strconv.FormatInt(offset, 10),
  1212  	})
  1213  	go GetInfoFromAnySharder(url, OpStorageSCGetUserSnapshots, cb)
  1214  	return
  1215  }
  1216  
  1217  // GetReadPoolInfo obtains information about read pool of a user.
  1218  func GetReadPoolInfo(clientID string, cb GetInfoCallback) (err error) {
  1219  	if err = CheckConfig(); err != nil {
  1220  		return
  1221  	}
  1222  	if clientID == "" {
  1223  		clientID = _config.wallet.ClientID
  1224  	}
  1225  	var url = withParams(STORAGESC_GET_READ_POOL_INFO, Params{
  1226  		"client_id": clientID,
  1227  	})
  1228  	go GetInfoFromSharders(url, OpStorageSCGetReadPoolInfo, cb)
  1229  	return
  1230  }
  1231  
  1232  // GetStakePoolInfo obtains information about stake pool of a blobber and
  1233  // related validator.
  1234  func GetStakePoolInfo(blobberID string, cb GetInfoCallback) (err error) {
  1235  	if err = CheckConfig(); err != nil {
  1236  		return
  1237  	}
  1238  	var url = withParams(STORAGESC_GET_STAKE_POOL_INFO, Params{
  1239  		"blobber_id": blobberID,
  1240  	})
  1241  	go GetInfoFromSharders(url, OpStorageSCGetStakePoolInfo, cb)
  1242  	return
  1243  }
  1244  
  1245  // GetStakePoolUserInfo for a user.
  1246  // # Inputs
  1247  //   - clientID: the id of wallet
  1248  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1249  func GetStakePoolUserInfo(clientID string, offset, limit int, cb GetInfoCallback) (err error) {
  1250  	if err = CheckConfig(); err != nil {
  1251  		return
  1252  	}
  1253  	if clientID == "" {
  1254  		clientID = _config.wallet.ClientID
  1255  	}
  1256  
  1257  	var url = withParams(STORAGESC_GET_STAKE_POOL_USER_INFO, Params{
  1258  		"client_id": clientID,
  1259  		"offset":    strconv.FormatInt(int64(offset), 10),
  1260  		"limit":     strconv.FormatInt(int64(limit), 10),
  1261  	})
  1262  	go GetInfoFromSharders(url, OpStorageSCGetStakePoolInfo, cb)
  1263  	return
  1264  }
  1265  
  1266  // GetStakeableBlobbers obtains list of all active blobbers that can be staked (i.e. still number of delegations < max_delegations)
  1267  // # Inputs
  1268  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1269  //   - limit: how many blobbers should be fetched
  1270  //   - offset: how many blobbers should be skipped
  1271  //   - active: only fetch active blobbers
  1272  func GetStakableBlobbers(cb GetInfoCallback, limit, offset int, active bool) {
  1273  	getBlobbersInternal(cb, active, limit, offset, true)
  1274  }
  1275  
  1276  // GetBlobbers obtains list of all active blobbers.
  1277  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1278  //   - limit: how many blobbers should be fetched
  1279  //   - offset: how many blobbers should be skipped
  1280  //   - active: only fetch active blobbers
  1281  func GetBlobbers(cb GetInfoCallback, limit, offset int, active bool) {
  1282  	getBlobbersInternal(cb, active, limit, offset, false)
  1283  }
  1284  
  1285  func getBlobbersInternal(cb GetInfoCallback, active bool, limit, offset int, stakable bool) {
  1286  	if err := CheckConfig(); err != nil {
  1287  		return
  1288  	}
  1289  
  1290  	var url = withParams(STORAGESC_GET_BLOBBERS, Params{
  1291  		"active":   strconv.FormatBool(active),
  1292  		"offset":   strconv.FormatInt(int64(offset), 10),
  1293  		"limit":    strconv.FormatInt(int64(limit), 10),
  1294  		"stakable": strconv.FormatBool(stakable),
  1295  	})
  1296  
  1297  	go GetInfoFromSharders(url, OpStorageSCGetBlobbers, cb)
  1298  }
  1299  
  1300  // GetBlobber obtains blobber information.
  1301  //   - blobberID: blobber id
  1302  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1303  func GetBlobber(blobberID string, cb GetInfoCallback) (err error) {
  1304  	if err = CheckConfig(); err != nil {
  1305  		return
  1306  	}
  1307  	var url = withParams(STORAGESC_GET_BLOBBER, Params{
  1308  		"blobber_id": blobberID,
  1309  	})
  1310  	go GetInfoFromSharders(url, OpStorageSCGetBlobber, cb)
  1311  	return
  1312  }
  1313  
  1314  // GetValidator obtains validator information.
  1315  //   - validatorID: validator id
  1316  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1317  func GetValidator(validatorID string, cb GetInfoCallback) (err error) {
  1318  	if err = CheckConfig(); err != nil {
  1319  		return
  1320  	}
  1321  	var url = withParams(STORAGESC_GET_VALIDATOR, Params{
  1322  		"validator_id": validatorID,
  1323  	})
  1324  	go GetInfoFromSharders(url, OpStorageSCGetBlobber, cb)
  1325  	return
  1326  }
  1327  
  1328  // GetAuthorizer obtains authorizer information from the sharders.
  1329  //   - authorizerID: authorizer id
  1330  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1331  func GetAuthorizer(authorizerID string, cb GetInfoCallback) (err error) {
  1332  	if err = CheckConfig(); err != nil {
  1333  		return
  1334  	}
  1335  	var url = withParams(GET_AUTHORIZER, Params{
  1336  		"id": authorizerID,
  1337  	})
  1338  	go GetInfoFromSharders(url, OpStorageSCGetBlobber, cb)
  1339  	return
  1340  }
  1341  
  1342  // GetMinerSharder obtains miner sharder information from the sharders.
  1343  //   - id: miner sharder id
  1344  //   - cb: info callback instance, carries the response of the GET request to the sharders
  1345  func GetMinerSharder(id string, cb GetInfoCallback) (err error) {
  1346  	if err = CheckConfig(); err != nil {
  1347  		return
  1348  	}
  1349  	var url = withParams(GET_MINERSC_NODE, Params{
  1350  		"id": id,
  1351  	})
  1352  	go GetInfoFromSharders(url, OpStorageSCGetBlobber, cb)
  1353  	return
  1354  }
  1355  
  1356  // GetTransactions query transactions from sharders
  1357  // # Inputs
  1358  //   - toClient:   	receiver
  1359  //   - fromClient: 	sender
  1360  //   - block_hash: 	block hash
  1361  //   - sort:				desc or asc
  1362  //   - limit: 			how many transactions should be fetched
  1363  //   - offset:			how many transactions should be skipped
  1364  //   - cb: 					callback to get result
  1365  func GetTransactions(toClient, fromClient, block_hash, sort string, limit, offset int, cb GetInfoCallback) (err error) {
  1366  	if err = CheckConfig(); err != nil {
  1367  		return
  1368  	}
  1369  
  1370  	params := Params{}
  1371  	if toClient != "" {
  1372  		params["to_client_id"] = toClient
  1373  	}
  1374  	if fromClient != "" {
  1375  		params["client_id"] = fromClient
  1376  	}
  1377  	if block_hash != "" {
  1378  		params["block_hash"] = block_hash
  1379  	}
  1380  	if sort != "" {
  1381  		params["sort"] = sort
  1382  	}
  1383  	if limit != 0 {
  1384  		l := strconv.Itoa(limit)
  1385  		params["limit"] = l
  1386  	}
  1387  	if offset != 0 {
  1388  		o := strconv.Itoa(offset)
  1389  		params["offset"] = o
  1390  	}
  1391  
  1392  	var u = withParams(STORAGESC_GET_TRANSACTIONS, params)
  1393  	go GetInfoFromSharders(u, OpStorageSCGetTransactions, cb)
  1394  	return
  1395  }
  1396  
  1397  func Encrypt(key, text string) (string, error) {
  1398  	keyBytes := []byte(key)
  1399  	textBytes := []byte(text)
  1400  	response, err := zboxutil.Encrypt(keyBytes, textBytes)
  1401  	if err != nil {
  1402  		return "", err
  1403  	}
  1404  	return hex.EncodeToString(response), nil
  1405  }
  1406  
  1407  // Decrypt decrypts encrypted text using the key.
  1408  //   - key: key to use for decryption
  1409  //   - text: text to decrypt
  1410  func Decrypt(key, text string) (string, error) {
  1411  	keyBytes := []byte(key)
  1412  	textBytes, _ := hex.DecodeString(text)
  1413  	response, err := zboxutil.Decrypt(keyBytes, textBytes)
  1414  	if err != nil {
  1415  		return "", err
  1416  	}
  1417  	return string(response), nil
  1418  }
  1419  
  1420  func CryptoJsEncrypt(passphrase, message string) (string, error) {
  1421  	o := openssl.New()
  1422  
  1423  	enc, err := o.EncryptBytes(passphrase, []byte(message), openssl.DigestMD5Sum)
  1424  	if err != nil {
  1425  		return "", err
  1426  	}
  1427  
  1428  	return string(enc), nil
  1429  }
  1430  
  1431  func CryptoJsDecrypt(passphrase, encryptedMessage string) (string, error) {
  1432  	o := openssl.New()
  1433  	dec, err := o.DecryptBytes(passphrase, []byte(encryptedMessage), openssl.DigestMD5Sum)
  1434  	if err != nil {
  1435  		return "", err
  1436  	}
  1437  
  1438  	return string(dec), nil
  1439  }
  1440  
  1441  // GetPublicEncryptionKey returns the public encryption key for the given mnemonic
  1442  func GetPublicEncryptionKey(mnemonic string) (string, error) {
  1443  	encScheme := encryption.NewEncryptionScheme()
  1444  	_, err := encScheme.Initialize(mnemonic)
  1445  	if err != nil {
  1446  		return "", err
  1447  	}
  1448  	return encScheme.GetPublicKey()
  1449  }