github.com/Finschia/finschia-sdk@v0.49.1/x/collection/msgs.go (about)

     1  package collection
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"unicode/utf8"
     7  
     8  	sdk "github.com/Finschia/finschia-sdk/types"
     9  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    10  	"github.com/Finschia/finschia-sdk/x/token/class"
    11  )
    12  
    13  const (
    14  	lengthClassID = 8
    15  
    16  	nameLengthLimit = 20
    17  	uriLengthLimit  = 1000
    18  	metaLengthLimit = 1000
    19  	changesLimit    = 100
    20  )
    21  
    22  var (
    23  	patternAll  = fmt.Sprintf(`[0-9a-f]{%d}`, lengthClassID)
    24  	patternZero = fmt.Sprintf(`0{%d}`, lengthClassID)
    25  
    26  	patternClassID          = patternAll
    27  	patternLegacyFTClassID  = fmt.Sprintf(`0[0-9a-f]{%d}`, lengthClassID-1)
    28  	patternLegacyNFTClassID = fmt.Sprintf(`[1-9a-f][0-9a-f]{%d}`, lengthClassID-1)
    29  
    30  	// regexps for class ids
    31  	reClassID          = regexp.MustCompile(fmt.Sprintf(`^%s$`, patternClassID))
    32  	reLegacyFTClassID  = regexp.MustCompile(fmt.Sprintf(`^%s$`, patternLegacyFTClassID))
    33  	reLegacyNFTClassID = regexp.MustCompile(fmt.Sprintf(`^%s$`, patternLegacyNFTClassID))
    34  
    35  	// regexps for token ids
    36  	reTokenID     = regexp.MustCompile(fmt.Sprintf(`^%s%s$`, patternClassID, patternAll))
    37  	reFTID        = regexp.MustCompile(fmt.Sprintf(`^%s%s$`, patternClassID, patternZero))
    38  	reLegacyNFTID = regexp.MustCompile(fmt.Sprintf(`^%s%s$`, patternLegacyNFTClassID, patternAll))
    39  )
    40  
    41  func validateAmount(amount sdk.Int) error {
    42  	if !amount.IsPositive() {
    43  		return ErrInvalidAmount.Wrapf("amount must be positive: %s", amount)
    44  	}
    45  	return nil
    46  }
    47  
    48  // deprecated
    49  func validateCoins(amount []Coin) error {
    50  	return validateCoinsWithIDValidator(amount, ValidateTokenID)
    51  }
    52  
    53  // deprecated
    54  func validateCoinsWithIDValidator(amount []Coin, validator func(string) error) error {
    55  	for _, amt := range amount {
    56  		if err := validator(amt.TokenId); err != nil {
    57  			return err
    58  		}
    59  		if err := validateAmount(amt.Amount); err != nil {
    60  			return err
    61  		}
    62  	}
    63  	return nil
    64  }
    65  
    66  func NewFTID(classID string) string {
    67  	return newTokenID(classID, sdk.ZeroUint())
    68  }
    69  
    70  func NewNFTID(classID string, number int) string {
    71  	return newTokenID(classID, sdk.NewUint(uint64(number)))
    72  }
    73  
    74  func newTokenID(classID string, number sdk.Uint) string {
    75  	numberFormat := "%0" + fmt.Sprintf("%d", lengthClassID) + "x"
    76  	return classID + fmt.Sprintf(numberFormat, number.Uint64())
    77  }
    78  
    79  func SplitTokenID(tokenID string) (classID string) {
    80  	return tokenID[:lengthClassID]
    81  }
    82  
    83  func ValidateContractID(id string) error {
    84  	return class.ValidateID(id)
    85  }
    86  
    87  func ValidateClassID(id string) error {
    88  	return validateID(id, reClassID)
    89  }
    90  
    91  // Deprecated: do not use (no successor).
    92  func ValidateLegacyFTClassID(id string) error {
    93  	return validateID(id, reLegacyFTClassID)
    94  }
    95  
    96  // Deprecated: do not use (no successor).
    97  func ValidateLegacyNFTClassID(id string) error {
    98  	// daphne emits ErrInvalidTokenID here, but it's against to the spec.
    99  	if err := validateID(id, reLegacyNFTClassID); err != nil {
   100  		return ErrInvalidTokenType.Wrap(err.Error())
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  func ValidateTokenID(id string) error {
   107  	if err := validateID(id, reTokenID); err != nil {
   108  		return ErrInvalidTokenID.Wrap(err.Error())
   109  	}
   110  
   111  	return nil
   112  }
   113  
   114  func ValidateFTID(id string) error {
   115  	if err := validateID(id, reFTID); err != nil {
   116  		return ErrInvalidTokenID.Wrapf("%s not ft", id)
   117  	}
   118  
   119  	return nil
   120  }
   121  
   122  func ValidateNFTID(id string) error {
   123  	if err := ValidateTokenID(id); err != nil {
   124  		return err
   125  	}
   126  	if err := ValidateFTID(id); err == nil {
   127  		return sdkerrors.ErrInvalidRequest.Wrapf("invalid id: %s", id)
   128  	}
   129  	return nil
   130  }
   131  
   132  // Deprecated: do not use (no successor).
   133  func ValidateLegacyNFTID(id string) error {
   134  	if err := validateID(id, reLegacyNFTID); err != nil {
   135  		return ErrInvalidTokenID.Wrap(err.Error())
   136  	}
   137  
   138  	return nil
   139  }
   140  
   141  func validateID(id string, reg *regexp.Regexp) error {
   142  	if !reg.MatchString(id) {
   143  		return sdkerrors.ErrInvalidRequest.Wrapf("invalid id: %s", id)
   144  	}
   145  	return nil
   146  }
   147  
   148  func validateName(name string) error {
   149  	if err := validateStringSize(name, nameLengthLimit, "name"); err != nil {
   150  		return ErrInvalidNameLength.Wrap(err.Error())
   151  	}
   152  
   153  	return nil
   154  }
   155  
   156  func validateURI(uri string) error {
   157  	if err := validateStringSize(uri, uriLengthLimit, "uri"); err != nil {
   158  		return ErrInvalidBaseImgURILength.Wrap(err.Error())
   159  	}
   160  
   161  	return nil
   162  }
   163  
   164  func validateMeta(meta string) error {
   165  	if err := validateStringSize(meta, metaLengthLimit, "meta"); err != nil {
   166  		return ErrInvalidMetaLength.Wrap(err.Error())
   167  	}
   168  
   169  	return nil
   170  }
   171  
   172  func validateStringSize(str string, limit int, name string) error {
   173  	if length := utf8.RuneCountInString(str); length > limit {
   174  		return sdkerrors.ErrInvalidRequest.Wrapf("%s cannot exceed %d in length: current %d", name, limit, length)
   175  	}
   176  	return nil
   177  }
   178  
   179  func validateDecimals(decimals int32) error {
   180  	if decimals < 0 || decimals > 18 {
   181  		return ErrInvalidTokenDecimals.Wrapf("got; %d", decimals)
   182  	}
   183  	return nil
   184  }
   185  
   186  func validateLegacyPermission(permission string) error {
   187  	return ValidatePermission(Permission(LegacyPermissionFromString(permission)))
   188  }
   189  
   190  func ValidatePermission(permission Permission) error {
   191  	if p := Permission_value[Permission_name[int32(permission)]]; p == 0 {
   192  		return sdkerrors.ErrInvalidPermission.Wrap(permission.String())
   193  	}
   194  	return nil
   195  }
   196  
   197  func validateContractChange(change Attribute) error {
   198  	validators := map[string]func(string) error{
   199  		AttributeKeyName.String():       validateName,
   200  		AttributeKeyBaseImgURI.String(): validateURI,
   201  		AttributeKeyMeta.String():       validateMeta,
   202  		AttributeKeyURI.String():        validateURI,
   203  	}
   204  
   205  	return validateChange(change, validators)
   206  }
   207  
   208  func validateTokenClassChange(change Attribute) error {
   209  	validators := map[string]func(string) error{
   210  		AttributeKeyName.String(): validateName,
   211  		AttributeKeyMeta.String(): validateMeta,
   212  	}
   213  
   214  	return validateChange(change, validators)
   215  }
   216  
   217  func validateChange(change Attribute, validators map[string]func(string) error) error {
   218  	validator, ok := validators[change.Key]
   219  	if !ok {
   220  		return ErrInvalidChangesField.Wrapf("invalid field: %s", change.Key)
   221  	}
   222  	return validator(change.Value)
   223  }
   224  
   225  func canonicalKey(key string) string {
   226  	convert := map[string]string{
   227  		AttributeKeyBaseImgURI.String(): AttributeKeyURI.String(),
   228  	}
   229  	if converted, ok := convert[key]; ok {
   230  		return converted
   231  	}
   232  	return key
   233  }
   234  
   235  var _ sdk.Msg = (*MsgSendFT)(nil)
   236  
   237  // ValidateBasic implements Msg.
   238  func (m MsgSendFT) ValidateBasic() error {
   239  	if err := ValidateContractID(m.ContractId); err != nil {
   240  		return err
   241  	}
   242  
   243  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   244  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   245  	}
   246  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   247  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   248  	}
   249  
   250  	if err := validateCoins(m.Amount); err != nil {
   251  		return err
   252  	}
   253  
   254  	return nil
   255  }
   256  
   257  // GetSigners implements Msg
   258  func (m MsgSendFT) GetSigners() []sdk.AccAddress {
   259  	signer, _ := sdk.AccAddressFromBech32(m.From)
   260  	return []sdk.AccAddress{signer}
   261  }
   262  
   263  // Type implements the LegacyMsg.Type method.
   264  func (m MsgSendFT) Type() string {
   265  	return sdk.MsgTypeURL(&m)
   266  }
   267  
   268  // Route implements the LegacyMsg.Route method.
   269  func (m MsgSendFT) Route() string {
   270  	return RouterKey
   271  }
   272  
   273  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   274  func (m MsgSendFT) GetSignBytes() []byte {
   275  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   276  }
   277  
   278  var _ sdk.Msg = (*MsgOperatorSendFT)(nil)
   279  
   280  // ValidateBasic implements Msg.
   281  func (m MsgOperatorSendFT) ValidateBasic() error {
   282  	if err := ValidateContractID(m.ContractId); err != nil {
   283  		return err
   284  	}
   285  
   286  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
   287  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
   288  	}
   289  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   290  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   291  	}
   292  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   293  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   294  	}
   295  
   296  	if err := validateCoins(m.Amount); err != nil {
   297  		return err
   298  	}
   299  
   300  	return nil
   301  }
   302  
   303  // GetSigners implements Msg
   304  func (m MsgOperatorSendFT) GetSigners() []sdk.AccAddress {
   305  	signer, _ := sdk.AccAddressFromBech32(m.Operator)
   306  	return []sdk.AccAddress{signer}
   307  }
   308  
   309  // Type implements the LegacyMsg.Type method.
   310  func (m MsgOperatorSendFT) Type() string {
   311  	return sdk.MsgTypeURL(&m)
   312  }
   313  
   314  // Route implements the LegacyMsg.Route method.
   315  func (m MsgOperatorSendFT) Route() string {
   316  	return RouterKey
   317  }
   318  
   319  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   320  func (m MsgOperatorSendFT) GetSignBytes() []byte {
   321  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   322  }
   323  
   324  var _ sdk.Msg = (*MsgSendNFT)(nil)
   325  
   326  // ValidateBasic implements Msg.
   327  func (m MsgSendNFT) ValidateBasic() error {
   328  	if err := ValidateContractID(m.ContractId); err != nil {
   329  		return err
   330  	}
   331  
   332  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   333  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   334  	}
   335  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   336  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   337  	}
   338  
   339  	if len(m.TokenIds) == 0 {
   340  		return ErrEmptyField.Wrap("token ids cannot be empty")
   341  	}
   342  	for _, id := range m.TokenIds {
   343  		if err := ValidateTokenID(id); err != nil {
   344  			return err
   345  		}
   346  	}
   347  
   348  	return nil
   349  }
   350  
   351  // GetSigners implements Msg
   352  func (m MsgSendNFT) GetSigners() []sdk.AccAddress {
   353  	signer, _ := sdk.AccAddressFromBech32(m.From)
   354  	return []sdk.AccAddress{signer}
   355  }
   356  
   357  // Type implements the LegacyMsg.Type method.
   358  func (m MsgSendNFT) Type() string {
   359  	return sdk.MsgTypeURL(&m)
   360  }
   361  
   362  // Route implements the LegacyMsg.Route method.
   363  func (m MsgSendNFT) Route() string {
   364  	return RouterKey
   365  }
   366  
   367  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   368  func (m MsgSendNFT) GetSignBytes() []byte {
   369  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   370  }
   371  
   372  var _ sdk.Msg = (*MsgOperatorSendNFT)(nil)
   373  
   374  // ValidateBasic implements Msg.
   375  func (m MsgOperatorSendNFT) ValidateBasic() error {
   376  	if err := ValidateContractID(m.ContractId); err != nil {
   377  		return err
   378  	}
   379  
   380  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
   381  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
   382  	}
   383  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   384  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   385  	}
   386  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   387  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   388  	}
   389  
   390  	if len(m.TokenIds) == 0 {
   391  		return ErrEmptyField.Wrap("token ids cannot be empty")
   392  	}
   393  	for _, id := range m.TokenIds {
   394  		if err := ValidateTokenID(id); err != nil {
   395  			return err
   396  		}
   397  	}
   398  
   399  	return nil
   400  }
   401  
   402  // GetSigners implements Msg
   403  func (m MsgOperatorSendNFT) GetSigners() []sdk.AccAddress {
   404  	signer, _ := sdk.AccAddressFromBech32(m.Operator)
   405  	return []sdk.AccAddress{signer}
   406  }
   407  
   408  // Type implements the LegacyMsg.Type method.
   409  func (m MsgOperatorSendNFT) Type() string {
   410  	return sdk.MsgTypeURL(&m)
   411  }
   412  
   413  // Route implements the LegacyMsg.Route method.
   414  func (m MsgOperatorSendNFT) Route() string {
   415  	return RouterKey
   416  }
   417  
   418  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   419  func (m MsgOperatorSendNFT) GetSignBytes() []byte {
   420  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   421  }
   422  
   423  var _ sdk.Msg = (*MsgAuthorizeOperator)(nil)
   424  
   425  // ValidateBasic implements Msg.
   426  func (m MsgAuthorizeOperator) ValidateBasic() error {
   427  	if err := ValidateContractID(m.ContractId); err != nil {
   428  		return err
   429  	}
   430  
   431  	if _, err := sdk.AccAddressFromBech32(m.Holder); err != nil {
   432  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid holder address: %s", m.Holder)
   433  	}
   434  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
   435  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
   436  	}
   437  
   438  	if m.Operator == m.Holder {
   439  		return ErrApproverProxySame
   440  	}
   441  
   442  	return nil
   443  }
   444  
   445  // GetSigners implements Msg
   446  func (m MsgAuthorizeOperator) GetSigners() []sdk.AccAddress {
   447  	signer, _ := sdk.AccAddressFromBech32(m.Holder)
   448  	return []sdk.AccAddress{signer}
   449  }
   450  
   451  // Type implements the LegacyMsg.Type method.
   452  func (m MsgAuthorizeOperator) Type() string {
   453  	return sdk.MsgTypeURL(&m)
   454  }
   455  
   456  // Route implements the LegacyMsg.Route method.
   457  func (m MsgAuthorizeOperator) Route() string {
   458  	return RouterKey
   459  }
   460  
   461  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   462  func (m MsgAuthorizeOperator) GetSignBytes() []byte {
   463  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   464  }
   465  
   466  var _ sdk.Msg = (*MsgRevokeOperator)(nil)
   467  
   468  // ValidateBasic implements Msg.
   469  func (m MsgRevokeOperator) ValidateBasic() error {
   470  	if err := ValidateContractID(m.ContractId); err != nil {
   471  		return err
   472  	}
   473  
   474  	if _, err := sdk.AccAddressFromBech32(m.Holder); err != nil {
   475  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid holder address: %s", m.Holder)
   476  	}
   477  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
   478  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
   479  	}
   480  
   481  	if m.Operator == m.Holder {
   482  		return ErrApproverProxySame
   483  	}
   484  
   485  	return nil
   486  }
   487  
   488  // GetSigners implements Msg
   489  func (m MsgRevokeOperator) GetSigners() []sdk.AccAddress {
   490  	signer, _ := sdk.AccAddressFromBech32(m.Holder)
   491  	return []sdk.AccAddress{signer}
   492  }
   493  
   494  // Type implements the LegacyMsg.Type method.
   495  func (m MsgRevokeOperator) Type() string {
   496  	return sdk.MsgTypeURL(&m)
   497  }
   498  
   499  // Route implements the LegacyMsg.Route method.
   500  func (m MsgRevokeOperator) Route() string {
   501  	return RouterKey
   502  }
   503  
   504  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   505  func (m MsgRevokeOperator) GetSignBytes() []byte {
   506  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   507  }
   508  
   509  var _ sdk.Msg = (*MsgCreateContract)(nil)
   510  
   511  // ValidateBasic implements Msg.
   512  func (m MsgCreateContract) ValidateBasic() error {
   513  	if _, err := sdk.AccAddressFromBech32(m.Owner); err != nil {
   514  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid owner address: %s", m.Owner)
   515  	}
   516  
   517  	if err := validateName(m.Name); err != nil {
   518  		return err
   519  	}
   520  
   521  	if err := validateURI(m.Uri); err != nil {
   522  		return err
   523  	}
   524  
   525  	if err := validateMeta(m.Meta); err != nil {
   526  		return err
   527  	}
   528  
   529  	return nil
   530  }
   531  
   532  // GetSigners implements Msg
   533  func (m MsgCreateContract) GetSigners() []sdk.AccAddress {
   534  	signer, _ := sdk.AccAddressFromBech32(m.Owner)
   535  	return []sdk.AccAddress{signer}
   536  }
   537  
   538  // Type implements the LegacyMsg.Type method.
   539  func (m MsgCreateContract) Type() string {
   540  	return sdk.MsgTypeURL(&m)
   541  }
   542  
   543  // Route implements the LegacyMsg.Route method.
   544  func (m MsgCreateContract) Route() string {
   545  	return RouterKey
   546  }
   547  
   548  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   549  func (m MsgCreateContract) GetSignBytes() []byte {
   550  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   551  }
   552  
   553  var _ sdk.Msg = (*MsgIssueFT)(nil)
   554  
   555  // ValidateBasic implements Msg.
   556  func (m MsgIssueFT) ValidateBasic() error {
   557  	if err := ValidateContractID(m.ContractId); err != nil {
   558  		return err
   559  	}
   560  
   561  	if _, err := sdk.AccAddressFromBech32(m.Owner); err != nil {
   562  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid owner address: %s", m.Owner)
   563  	}
   564  
   565  	if len(m.Name) == 0 {
   566  		return ErrInvalidTokenName.Wrapf("empty name")
   567  	}
   568  	if err := validateName(m.Name); err != nil {
   569  		return err
   570  	}
   571  
   572  	if err := validateMeta(m.Meta); err != nil {
   573  		return err
   574  	}
   575  
   576  	if err := validateDecimals(m.Decimals); err != nil {
   577  		return err
   578  	}
   579  
   580  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   581  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   582  	}
   583  
   584  	// daphne compat.
   585  	if m.Amount.Equal(sdk.OneInt()) && m.Decimals == 0 && !m.Mintable {
   586  		return ErrInvalidIssueFT.Wrap("invalid issue of ft")
   587  	}
   588  
   589  	return nil
   590  }
   591  
   592  // GetSigners implements Msg
   593  func (m MsgIssueFT) GetSigners() []sdk.AccAddress {
   594  	signer, _ := sdk.AccAddressFromBech32(m.Owner)
   595  	return []sdk.AccAddress{signer}
   596  }
   597  
   598  // Type implements the LegacyMsg.Type method.
   599  func (m MsgIssueFT) Type() string {
   600  	return sdk.MsgTypeURL(&m)
   601  }
   602  
   603  // Route implements the LegacyMsg.Route method.
   604  func (m MsgIssueFT) Route() string {
   605  	return RouterKey
   606  }
   607  
   608  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   609  func (m MsgIssueFT) GetSignBytes() []byte {
   610  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   611  }
   612  
   613  var _ sdk.Msg = (*MsgIssueNFT)(nil)
   614  
   615  // ValidateBasic implements Msg.
   616  func (m MsgIssueNFT) ValidateBasic() error {
   617  	if err := ValidateContractID(m.ContractId); err != nil {
   618  		return err
   619  	}
   620  
   621  	if err := validateName(m.Name); err != nil {
   622  		return err
   623  	}
   624  
   625  	if err := validateMeta(m.Meta); err != nil {
   626  		return err
   627  	}
   628  
   629  	if _, err := sdk.AccAddressFromBech32(m.Owner); err != nil {
   630  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid owner address: %s", m.Owner)
   631  	}
   632  
   633  	return nil
   634  }
   635  
   636  // GetSigners implements Msg
   637  func (m MsgIssueNFT) GetSigners() []sdk.AccAddress {
   638  	signer, _ := sdk.AccAddressFromBech32(m.Owner)
   639  	return []sdk.AccAddress{signer}
   640  }
   641  
   642  // Type implements the LegacyMsg.Type method.
   643  func (m MsgIssueNFT) Type() string {
   644  	return sdk.MsgTypeURL(&m)
   645  }
   646  
   647  // Route implements the LegacyMsg.Route method.
   648  func (m MsgIssueNFT) Route() string {
   649  	return RouterKey
   650  }
   651  
   652  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   653  func (m MsgIssueNFT) GetSignBytes() []byte {
   654  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   655  }
   656  
   657  var _ sdk.Msg = (*MsgMintFT)(nil)
   658  
   659  // ValidateBasic implements Msg.
   660  func (m MsgMintFT) ValidateBasic() error {
   661  	if err := ValidateContractID(m.ContractId); err != nil {
   662  		return err
   663  	}
   664  
   665  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   666  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   667  	}
   668  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   669  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   670  	}
   671  
   672  	if err := validateCoins(m.Amount); err != nil {
   673  		return err
   674  	}
   675  
   676  	return nil
   677  }
   678  
   679  // GetSigners implements Msg
   680  func (m MsgMintFT) GetSigners() []sdk.AccAddress {
   681  	signer, _ := sdk.AccAddressFromBech32(m.From)
   682  	return []sdk.AccAddress{signer}
   683  }
   684  
   685  // Type implements the LegacyMsg.Type method.
   686  func (m MsgMintFT) Type() string {
   687  	return sdk.MsgTypeURL(&m)
   688  }
   689  
   690  // Route implements the LegacyMsg.Route method.
   691  func (m MsgMintFT) Route() string {
   692  	return RouterKey
   693  }
   694  
   695  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   696  func (m MsgMintFT) GetSignBytes() []byte {
   697  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   698  }
   699  
   700  var _ sdk.Msg = (*MsgMintNFT)(nil)
   701  
   702  // ValidateBasic implements Msg.
   703  func (m MsgMintNFT) ValidateBasic() error {
   704  	if err := ValidateContractID(m.ContractId); err != nil {
   705  		return err
   706  	}
   707  
   708  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   709  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   710  	}
   711  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
   712  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
   713  	}
   714  
   715  	if len(m.Params) == 0 {
   716  		return ErrEmptyField.Wrap("mint params cannot be empty")
   717  	}
   718  	for _, param := range m.Params {
   719  		classID := param.TokenType
   720  		if err := ValidateLegacyNFTClassID(classID); err != nil {
   721  			return err
   722  		}
   723  
   724  		if len(param.Name) == 0 {
   725  			return ErrInvalidTokenName
   726  		}
   727  		if err := validateName(param.Name); err != nil {
   728  			return err
   729  		}
   730  
   731  		if err := validateMeta(param.Meta); err != nil {
   732  			return err
   733  		}
   734  	}
   735  
   736  	return nil
   737  }
   738  
   739  // GetSigners implements Msg
   740  func (m MsgMintNFT) GetSigners() []sdk.AccAddress {
   741  	signer, _ := sdk.AccAddressFromBech32(m.From)
   742  	return []sdk.AccAddress{signer}
   743  }
   744  
   745  // Type implements the LegacyMsg.Type method.
   746  func (m MsgMintNFT) Type() string {
   747  	return sdk.MsgTypeURL(&m)
   748  }
   749  
   750  // Route implements the LegacyMsg.Route method.
   751  func (m MsgMintNFT) Route() string {
   752  	return RouterKey
   753  }
   754  
   755  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   756  func (m MsgMintNFT) GetSignBytes() []byte {
   757  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   758  }
   759  
   760  var _ sdk.Msg = (*MsgBurnFT)(nil)
   761  
   762  // ValidateBasic implements Msg.
   763  func (m MsgBurnFT) ValidateBasic() error {
   764  	if err := ValidateContractID(m.ContractId); err != nil {
   765  		return err
   766  	}
   767  
   768  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   769  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   770  	}
   771  
   772  	if err := validateCoins(m.Amount); err != nil {
   773  		return err
   774  	}
   775  
   776  	return nil
   777  }
   778  
   779  // GetSigners implements Msg
   780  func (m MsgBurnFT) GetSigners() []sdk.AccAddress {
   781  	signer, _ := sdk.AccAddressFromBech32(m.From)
   782  	return []sdk.AccAddress{signer}
   783  }
   784  
   785  // Type implements the LegacyMsg.Type method.
   786  func (m MsgBurnFT) Type() string {
   787  	return sdk.MsgTypeURL(&m)
   788  }
   789  
   790  // Route implements the LegacyMsg.Route method.
   791  func (m MsgBurnFT) Route() string {
   792  	return RouterKey
   793  }
   794  
   795  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   796  func (m MsgBurnFT) GetSignBytes() []byte {
   797  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   798  }
   799  
   800  var _ sdk.Msg = (*MsgOperatorBurnFT)(nil)
   801  
   802  // ValidateBasic implements Msg.
   803  func (m MsgOperatorBurnFT) ValidateBasic() error {
   804  	if err := ValidateContractID(m.ContractId); err != nil {
   805  		return err
   806  	}
   807  
   808  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
   809  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
   810  	}
   811  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   812  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   813  	}
   814  
   815  	if err := validateCoins(m.Amount); err != nil {
   816  		return err
   817  	}
   818  
   819  	return nil
   820  }
   821  
   822  // GetSigners implements Msg
   823  func (m MsgOperatorBurnFT) GetSigners() []sdk.AccAddress {
   824  	signer, _ := sdk.AccAddressFromBech32(m.Operator)
   825  	return []sdk.AccAddress{signer}
   826  }
   827  
   828  // Type implements the LegacyMsg.Type method.
   829  func (m MsgOperatorBurnFT) Type() string {
   830  	return sdk.MsgTypeURL(&m)
   831  }
   832  
   833  // Route implements the LegacyMsg.Route method.
   834  func (m MsgOperatorBurnFT) Route() string {
   835  	return RouterKey
   836  }
   837  
   838  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   839  func (m MsgOperatorBurnFT) GetSignBytes() []byte {
   840  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   841  }
   842  
   843  var _ sdk.Msg = (*MsgBurnNFT)(nil)
   844  
   845  // ValidateBasic implements Msg.
   846  func (m MsgBurnNFT) ValidateBasic() error {
   847  	if err := ValidateContractID(m.ContractId); err != nil {
   848  		return err
   849  	}
   850  
   851  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   852  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   853  	}
   854  
   855  	if len(m.TokenIds) == 0 {
   856  		return ErrEmptyField.Wrap("token ids cannot be empty")
   857  	}
   858  	for _, id := range m.TokenIds {
   859  		if err := ValidateLegacyNFTID(id); err != nil {
   860  			return err
   861  		}
   862  	}
   863  
   864  	return nil
   865  }
   866  
   867  // GetSigners implements Msg
   868  func (m MsgBurnNFT) GetSigners() []sdk.AccAddress {
   869  	signer, _ := sdk.AccAddressFromBech32(m.From)
   870  	return []sdk.AccAddress{signer}
   871  }
   872  
   873  // Type implements the LegacyMsg.Type method.
   874  func (m MsgBurnNFT) Type() string {
   875  	return sdk.MsgTypeURL(&m)
   876  }
   877  
   878  // Route implements the LegacyMsg.Route method.
   879  func (m MsgBurnNFT) Route() string {
   880  	return RouterKey
   881  }
   882  
   883  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   884  func (m MsgBurnNFT) GetSignBytes() []byte {
   885  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   886  }
   887  
   888  var _ sdk.Msg = (*MsgOperatorBurnNFT)(nil)
   889  
   890  // ValidateBasic implements Msg.
   891  func (m MsgOperatorBurnNFT) ValidateBasic() error {
   892  	if err := ValidateContractID(m.ContractId); err != nil {
   893  		return err
   894  	}
   895  
   896  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
   897  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
   898  	}
   899  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
   900  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
   901  	}
   902  
   903  	if len(m.TokenIds) == 0 {
   904  		return ErrEmptyField.Wrap("token ids cannot be empty")
   905  	}
   906  	for _, id := range m.TokenIds {
   907  		if err := ValidateLegacyNFTID(id); err != nil {
   908  			return err
   909  		}
   910  	}
   911  
   912  	return nil
   913  }
   914  
   915  // GetSigners implements Msg
   916  func (m MsgOperatorBurnNFT) GetSigners() []sdk.AccAddress {
   917  	signer, _ := sdk.AccAddressFromBech32(m.Operator)
   918  	return []sdk.AccAddress{signer}
   919  }
   920  
   921  // Type implements the LegacyMsg.Type method.
   922  func (m MsgOperatorBurnNFT) Type() string {
   923  	return sdk.MsgTypeURL(&m)
   924  }
   925  
   926  // Route implements the LegacyMsg.Route method.
   927  func (m MsgOperatorBurnNFT) Route() string {
   928  	return RouterKey
   929  }
   930  
   931  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
   932  func (m MsgOperatorBurnNFT) GetSignBytes() []byte {
   933  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
   934  }
   935  
   936  var _ sdk.Msg = (*MsgModify)(nil)
   937  
   938  // ValidateBasic implements Msg.
   939  func (m MsgModify) ValidateBasic() error {
   940  	UpdateMsgModify(&m)
   941  
   942  	if err := ValidateContractID(m.ContractId); err != nil {
   943  		return err
   944  	}
   945  
   946  	if _, err := sdk.AccAddressFromBech32(m.Owner); err != nil {
   947  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid owner address: %s", m.Owner)
   948  	}
   949  
   950  	if len(m.TokenType) != 0 {
   951  		classID := m.TokenType
   952  		if err := ValidateClassID(classID); err != nil {
   953  			return ErrInvalidTokenType.Wrap(err.Error())
   954  		}
   955  		if err := ValidateLegacyFTClassID(classID); err == nil && len(m.TokenIndex) == 0 {
   956  			return ErrTokenTypeFTWithoutIndex.Wrap("fungible token type without index")
   957  		}
   958  	}
   959  
   960  	if len(m.TokenIndex) != 0 {
   961  		tokenID := m.TokenType + m.TokenIndex
   962  		if err := ValidateTokenID(tokenID); err != nil {
   963  			return ErrInvalidTokenIndex.Wrap(err.Error())
   964  		}
   965  		// reject modifying nft class with token index filled (daphne compat.)
   966  		if ValidateLegacyNFTID(tokenID) == nil && ValidateFTID(tokenID) == nil {
   967  			return ErrInvalidTokenIndex.Wrap("cannot modify nft class with index filled")
   968  		}
   969  	}
   970  
   971  	validator := validateTokenClassChange
   972  	if len(m.TokenType) == 0 {
   973  		if len(m.TokenIndex) == 0 {
   974  			validator = validateContractChange
   975  		} else {
   976  			return ErrTokenIndexWithoutType.Wrap("token index without type")
   977  		}
   978  	}
   979  	if len(m.Changes) == 0 {
   980  		return ErrEmptyChanges.Wrap("empty changes")
   981  	}
   982  	if len(m.Changes) > changesLimit {
   983  		return ErrInvalidChangesFieldCount.Wrapf("the number of changes exceeds the limit: %d > %d", len(m.Changes), changesLimit)
   984  	}
   985  	seenKeys := map[string]bool{}
   986  	for _, change := range m.Changes {
   987  		key := change.Key
   988  		if seenKeys[key] {
   989  			return ErrDuplicateChangesField.Wrapf("duplicate keys: %s", change.Key)
   990  		}
   991  		seenKeys[key] = true
   992  
   993  		attribute := Attribute{
   994  			Key:   change.Key,
   995  			Value: change.Value,
   996  		}
   997  		if err := validator(attribute); err != nil {
   998  			return err
   999  		}
  1000  	}
  1001  
  1002  	return nil
  1003  }
  1004  
  1005  func UpdateMsgModify(msg *MsgModify) {
  1006  	for i, change := range msg.Changes {
  1007  		key := change.Key
  1008  		converted := canonicalKey(key)
  1009  		if converted != key {
  1010  			msg.Changes[i].Key = converted
  1011  		}
  1012  	}
  1013  }
  1014  
  1015  // GetSigners implements Msg
  1016  func (m MsgModify) GetSigners() []sdk.AccAddress {
  1017  	signer, _ := sdk.AccAddressFromBech32(m.Owner)
  1018  	return []sdk.AccAddress{signer}
  1019  }
  1020  
  1021  // Type implements the LegacyMsg.Type method.
  1022  func (m MsgModify) Type() string {
  1023  	return sdk.MsgTypeURL(&m)
  1024  }
  1025  
  1026  // Route implements the LegacyMsg.Route method.
  1027  func (m MsgModify) Route() string {
  1028  	return RouterKey
  1029  }
  1030  
  1031  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1032  func (m MsgModify) GetSignBytes() []byte {
  1033  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1034  }
  1035  
  1036  var _ sdk.Msg = (*MsgGrantPermission)(nil)
  1037  
  1038  // ValidateBasic implements Msg.
  1039  func (m MsgGrantPermission) ValidateBasic() error {
  1040  	if err := ValidateContractID(m.ContractId); err != nil {
  1041  		return err
  1042  	}
  1043  
  1044  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
  1045  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
  1046  	}
  1047  	if _, err := sdk.AccAddressFromBech32(m.To); err != nil {
  1048  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid to address: %s", m.To)
  1049  	}
  1050  
  1051  	if err := validateLegacyPermission(m.Permission); err != nil {
  1052  		return err
  1053  	}
  1054  
  1055  	return nil
  1056  }
  1057  
  1058  // GetSigners implements Msg
  1059  func (m MsgGrantPermission) GetSigners() []sdk.AccAddress {
  1060  	signer, _ := sdk.AccAddressFromBech32(m.From)
  1061  	return []sdk.AccAddress{signer}
  1062  }
  1063  
  1064  // Type implements the LegacyMsg.Type method.
  1065  func (m MsgGrantPermission) Type() string {
  1066  	return sdk.MsgTypeURL(&m)
  1067  }
  1068  
  1069  // Route implements the LegacyMsg.Route method.
  1070  func (m MsgGrantPermission) Route() string {
  1071  	return RouterKey
  1072  }
  1073  
  1074  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1075  func (m MsgGrantPermission) GetSignBytes() []byte {
  1076  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1077  }
  1078  
  1079  var _ sdk.Msg = (*MsgRevokePermission)(nil)
  1080  
  1081  // ValidateBasic implements Msg.
  1082  func (m MsgRevokePermission) ValidateBasic() error {
  1083  	if err := ValidateContractID(m.ContractId); err != nil {
  1084  		return err
  1085  	}
  1086  
  1087  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
  1088  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
  1089  	}
  1090  
  1091  	if err := validateLegacyPermission(m.Permission); err != nil {
  1092  		return err
  1093  	}
  1094  
  1095  	return nil
  1096  }
  1097  
  1098  // GetSigners implements Msg
  1099  func (m MsgRevokePermission) GetSigners() []sdk.AccAddress {
  1100  	signer, _ := sdk.AccAddressFromBech32(m.From)
  1101  	return []sdk.AccAddress{signer}
  1102  }
  1103  
  1104  // Type implements the LegacyMsg.Type method.
  1105  func (m MsgRevokePermission) Type() string {
  1106  	return sdk.MsgTypeURL(&m)
  1107  }
  1108  
  1109  // Route implements the LegacyMsg.Route method.
  1110  func (m MsgRevokePermission) Route() string {
  1111  	return RouterKey
  1112  }
  1113  
  1114  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1115  func (m MsgRevokePermission) GetSignBytes() []byte {
  1116  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1117  }
  1118  
  1119  var _ sdk.Msg = (*MsgAttach)(nil)
  1120  
  1121  // ValidateBasic implements Msg.
  1122  func (m MsgAttach) ValidateBasic() error {
  1123  	if err := ValidateContractID(m.ContractId); err != nil {
  1124  		return err
  1125  	}
  1126  
  1127  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
  1128  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
  1129  	}
  1130  
  1131  	if err := ValidateTokenID(m.TokenId); err != nil {
  1132  		return err
  1133  	}
  1134  	if err := ValidateTokenID(m.ToTokenId); err != nil {
  1135  		return err
  1136  	}
  1137  
  1138  	if m.TokenId == m.ToTokenId {
  1139  		return ErrCannotAttachToItself.Wrap("cannot attach token to itself")
  1140  	}
  1141  
  1142  	return nil
  1143  }
  1144  
  1145  // GetSigners implements Msg
  1146  func (m MsgAttach) GetSigners() []sdk.AccAddress {
  1147  	signer, _ := sdk.AccAddressFromBech32(m.From)
  1148  	return []sdk.AccAddress{signer}
  1149  }
  1150  
  1151  // Type implements the LegacyMsg.Type method.
  1152  func (m MsgAttach) Type() string {
  1153  	return sdk.MsgTypeURL(&m)
  1154  }
  1155  
  1156  // Route implements the LegacyMsg.Route method.
  1157  func (m MsgAttach) Route() string {
  1158  	return RouterKey
  1159  }
  1160  
  1161  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1162  func (m MsgAttach) GetSignBytes() []byte {
  1163  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1164  }
  1165  
  1166  var _ sdk.Msg = (*MsgDetach)(nil)
  1167  
  1168  // ValidateBasic implements Msg.
  1169  func (m MsgDetach) ValidateBasic() error {
  1170  	if err := ValidateContractID(m.ContractId); err != nil {
  1171  		return err
  1172  	}
  1173  
  1174  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
  1175  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
  1176  	}
  1177  
  1178  	if err := ValidateTokenID(m.TokenId); err != nil {
  1179  		return err
  1180  	}
  1181  
  1182  	return nil
  1183  }
  1184  
  1185  // GetSigners implements Msg
  1186  func (m MsgDetach) GetSigners() []sdk.AccAddress {
  1187  	signer, _ := sdk.AccAddressFromBech32(m.From)
  1188  	return []sdk.AccAddress{signer}
  1189  }
  1190  
  1191  // Type implements the LegacyMsg.Type method.
  1192  func (m MsgDetach) Type() string {
  1193  	return sdk.MsgTypeURL(&m)
  1194  }
  1195  
  1196  // Route implements the LegacyMsg.Route method.
  1197  func (m MsgDetach) Route() string {
  1198  	return RouterKey
  1199  }
  1200  
  1201  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1202  func (m MsgDetach) GetSignBytes() []byte {
  1203  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1204  }
  1205  
  1206  var _ sdk.Msg = (*MsgOperatorAttach)(nil)
  1207  
  1208  // ValidateBasic implements Msg.
  1209  func (m MsgOperatorAttach) ValidateBasic() error {
  1210  	if err := ValidateContractID(m.ContractId); err != nil {
  1211  		return err
  1212  	}
  1213  
  1214  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
  1215  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
  1216  	}
  1217  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
  1218  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
  1219  	}
  1220  
  1221  	if err := ValidateTokenID(m.TokenId); err != nil {
  1222  		return err
  1223  	}
  1224  	if err := ValidateTokenID(m.ToTokenId); err != nil {
  1225  		return err
  1226  	}
  1227  
  1228  	if m.TokenId == m.ToTokenId {
  1229  		return ErrCannotAttachToItself.Wrap("cannot attach token to itself")
  1230  	}
  1231  
  1232  	return nil
  1233  }
  1234  
  1235  // GetSigners implements Msg
  1236  func (m MsgOperatorAttach) GetSigners() []sdk.AccAddress {
  1237  	signer, _ := sdk.AccAddressFromBech32(m.Operator)
  1238  	return []sdk.AccAddress{signer}
  1239  }
  1240  
  1241  // Type implements the LegacyMsg.Type method.
  1242  func (m MsgOperatorAttach) Type() string {
  1243  	return sdk.MsgTypeURL(&m)
  1244  }
  1245  
  1246  // Route implements the LegacyMsg.Route method.
  1247  func (m MsgOperatorAttach) Route() string {
  1248  	return RouterKey
  1249  }
  1250  
  1251  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1252  func (m MsgOperatorAttach) GetSignBytes() []byte {
  1253  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1254  }
  1255  
  1256  var _ sdk.Msg = (*MsgOperatorDetach)(nil)
  1257  
  1258  // ValidateBasic implements Msg.
  1259  func (m MsgOperatorDetach) ValidateBasic() error {
  1260  	if err := ValidateContractID(m.ContractId); err != nil {
  1261  		return err
  1262  	}
  1263  
  1264  	if _, err := sdk.AccAddressFromBech32(m.Operator); err != nil {
  1265  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid operator address: %s", m.Operator)
  1266  	}
  1267  	if _, err := sdk.AccAddressFromBech32(m.From); err != nil {
  1268  		return sdkerrors.ErrInvalidAddress.Wrapf("invalid from address: %s", m.From)
  1269  	}
  1270  
  1271  	if err := ValidateTokenID(m.TokenId); err != nil {
  1272  		return err
  1273  	}
  1274  
  1275  	return nil
  1276  }
  1277  
  1278  // GetSigners implements Msg
  1279  func (m MsgOperatorDetach) GetSigners() []sdk.AccAddress {
  1280  	signer, _ := sdk.AccAddressFromBech32(m.Operator)
  1281  	return []sdk.AccAddress{signer}
  1282  }
  1283  
  1284  // Type implements the LegacyMsg.Type method.
  1285  func (m MsgOperatorDetach) Type() string {
  1286  	return sdk.MsgTypeURL(&m)
  1287  }
  1288  
  1289  // Route implements the LegacyMsg.Route method.
  1290  func (m MsgOperatorDetach) Route() string {
  1291  	return RouterKey
  1292  }
  1293  
  1294  // GetSignBytes implements the LegacyMsg.GetSignBytes method.
  1295  func (m MsgOperatorDetach) GetSignBytes() []byte {
  1296  	return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
  1297  }