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 }