github.com/Finschia/finschia-sdk@v0.48.1/x/collection/msgs_test.go (about) 1 package collection_test 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/stretchr/testify/require" 9 10 "github.com/Finschia/finschia-sdk/crypto/keys/secp256k1" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 13 "github.com/Finschia/finschia-sdk/x/auth/legacy/legacytx" 14 "github.com/Finschia/finschia-sdk/x/collection" 15 "github.com/Finschia/finschia-sdk/x/token/class" 16 ) 17 18 func TestMsgSendFT(t *testing.T) { 19 addrs := make([]sdk.AccAddress, 2) 20 for i := range addrs { 21 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 22 } 23 24 amount := collection.NewCoins( 25 collection.NewFTCoin("00bab10c", sdk.OneInt()), 26 ) 27 28 testCases := map[string]struct { 29 contractID string 30 from sdk.AccAddress 31 to sdk.AccAddress 32 amount []collection.Coin 33 err error 34 panic bool 35 }{ 36 "valid msg": { 37 contractID: "deadbeef", 38 from: addrs[0], 39 to: addrs[1], 40 amount: amount, 41 }, 42 "invalid from": { 43 contractID: "deadbeef", 44 to: addrs[1], 45 amount: amount, 46 err: sdkerrors.ErrInvalidAddress, 47 }, 48 "invalid contract id": { 49 from: addrs[0], 50 to: addrs[1], 51 amount: amount, 52 err: class.ErrInvalidContractID, 53 }, 54 "invalid to": { 55 contractID: "deadbeef", 56 from: addrs[0], 57 amount: amount, 58 err: sdkerrors.ErrInvalidAddress, 59 }, 60 "nil amount": { 61 contractID: "deadbeef", 62 from: addrs[0], 63 to: addrs[1], 64 amount: []collection.Coin{{ 65 TokenId: collection.NewFTID("00bab10c"), 66 }}, 67 panic: true, 68 }, 69 "zero amount": { 70 contractID: "deadbeef", 71 from: addrs[0], 72 to: addrs[1], 73 amount: []collection.Coin{{ 74 TokenId: collection.NewFTID("00bab10c"), 75 Amount: sdk.ZeroInt(), 76 }}, 77 err: collection.ErrInvalidAmount, 78 }, 79 "invalid token id": { 80 contractID: "deadbeef", 81 from: addrs[0], 82 to: addrs[1], 83 amount: []collection.Coin{{ 84 Amount: sdk.OneInt(), 85 }}, 86 err: collection.ErrInvalidTokenID, 87 }, 88 } 89 90 for name, tc := range testCases { 91 t.Run(name, func(t *testing.T) { 92 msg := collection.MsgSendFT{ 93 ContractId: tc.contractID, 94 From: tc.from.String(), 95 To: tc.to.String(), 96 Amount: tc.amount, 97 } 98 99 if tc.panic { 100 require.Panics(t, func() { msg.ValidateBasic() }) 101 return 102 } 103 104 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 105 if tc.err != nil { 106 return 107 } 108 109 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 110 }) 111 } 112 } 113 114 func TestMsgOperatorSendFT(t *testing.T) { 115 addrs := make([]sdk.AccAddress, 3) 116 for i := range addrs { 117 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 118 } 119 120 amount := collection.NewCoins( 121 collection.NewFTCoin("00bab10c", sdk.OneInt()), 122 ) 123 124 testCases := map[string]struct { 125 contractID string 126 operator sdk.AccAddress 127 from sdk.AccAddress 128 to sdk.AccAddress 129 amount []collection.Coin 130 err error 131 }{ 132 "valid msg": { 133 contractID: "deadbeef", 134 operator: addrs[0], 135 from: addrs[1], 136 to: addrs[2], 137 amount: amount, 138 }, 139 "invalid operator": { 140 contractID: "deadbeef", 141 from: addrs[1], 142 to: addrs[2], 143 amount: amount, 144 err: sdkerrors.ErrInvalidAddress, 145 }, 146 "invalid contract id": { 147 operator: addrs[0], 148 from: addrs[1], 149 to: addrs[2], 150 amount: amount, 151 err: class.ErrInvalidContractID, 152 }, 153 "invalid from": { 154 contractID: "deadbeef", 155 operator: addrs[0], 156 to: addrs[1], 157 amount: amount, 158 err: sdkerrors.ErrInvalidAddress, 159 }, 160 "invalid to": { 161 contractID: "deadbeef", 162 operator: addrs[0], 163 from: addrs[1], 164 amount: amount, 165 err: sdkerrors.ErrInvalidAddress, 166 }, 167 "invalid amount": { 168 contractID: "deadbeef", 169 operator: addrs[0], 170 from: addrs[1], 171 to: addrs[2], 172 amount: []collection.Coin{{ 173 TokenId: collection.NewFTID("00bab10c"), 174 Amount: sdk.ZeroInt(), 175 }}, 176 err: collection.ErrInvalidAmount, 177 }, 178 "invalid denom": { 179 contractID: "deadbeef", 180 operator: addrs[0], 181 from: addrs[1], 182 to: addrs[2], 183 amount: []collection.Coin{{ 184 Amount: sdk.OneInt(), 185 }}, 186 err: collection.ErrInvalidTokenID, 187 }, 188 } 189 190 for name, tc := range testCases { 191 t.Run(name, func(t *testing.T) { 192 msg := collection.MsgOperatorSendFT{ 193 ContractId: tc.contractID, 194 Operator: tc.operator.String(), 195 From: tc.from.String(), 196 To: tc.to.String(), 197 Amount: tc.amount, 198 } 199 200 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 201 if tc.err != nil { 202 return 203 } 204 205 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 206 }) 207 } 208 } 209 210 func TestMsgSendNFT(t *testing.T) { 211 addrs := make([]sdk.AccAddress, 2) 212 for i := range addrs { 213 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 214 } 215 216 ids := []string{collection.NewNFTID("deadbeef", 1)} 217 218 testCases := map[string]struct { 219 contractID string 220 from sdk.AccAddress 221 to sdk.AccAddress 222 ids []string 223 err error 224 }{ 225 "valid msg": { 226 contractID: "deadbeef", 227 from: addrs[0], 228 to: addrs[1], 229 ids: ids, 230 }, 231 "invalid from": { 232 contractID: "deadbeef", 233 to: addrs[1], 234 ids: ids, 235 err: sdkerrors.ErrInvalidAddress, 236 }, 237 "invalid contract id": { 238 from: addrs[0], 239 to: addrs[1], 240 ids: ids, 241 err: class.ErrInvalidContractID, 242 }, 243 "invalid to": { 244 contractID: "deadbeef", 245 from: addrs[0], 246 ids: ids, 247 err: sdkerrors.ErrInvalidAddress, 248 }, 249 "empty token ids": { 250 contractID: "deadbeef", 251 from: addrs[0], 252 to: addrs[1], 253 err: collection.ErrEmptyField, 254 }, 255 "invalid token ids": { 256 contractID: "deadbeef", 257 from: addrs[0], 258 to: addrs[1], 259 ids: []string{""}, 260 err: collection.ErrInvalidTokenID, 261 }, 262 } 263 264 for name, tc := range testCases { 265 t.Run(name, func(t *testing.T) { 266 msg := collection.MsgSendNFT{ 267 ContractId: tc.contractID, 268 From: tc.from.String(), 269 To: tc.to.String(), 270 TokenIds: tc.ids, 271 } 272 273 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 274 if tc.err != nil { 275 return 276 } 277 278 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 279 }) 280 } 281 } 282 283 func TestMsgOperatorSendNFT(t *testing.T) { 284 addrs := make([]sdk.AccAddress, 3) 285 for i := range addrs { 286 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 287 } 288 289 ids := []string{collection.NewNFTID("deadbeef", 1)} 290 291 testCases := map[string]struct { 292 contractID string 293 operator sdk.AccAddress 294 from sdk.AccAddress 295 to sdk.AccAddress 296 ids []string 297 err error 298 }{ 299 "valid msg": { 300 contractID: "deadbeef", 301 operator: addrs[0], 302 from: addrs[1], 303 to: addrs[2], 304 ids: ids, 305 }, 306 "invalid operator": { 307 contractID: "deadbeef", 308 from: addrs[1], 309 to: addrs[2], 310 ids: ids, 311 err: sdkerrors.ErrInvalidAddress, 312 }, 313 "invalid contract id": { 314 operator: addrs[0], 315 from: addrs[1], 316 to: addrs[2], 317 ids: ids, 318 err: class.ErrInvalidContractID, 319 }, 320 "invalid from": { 321 contractID: "deadbeef", 322 operator: addrs[0], 323 to: addrs[1], 324 ids: ids, 325 err: sdkerrors.ErrInvalidAddress, 326 }, 327 "invalid to": { 328 contractID: "deadbeef", 329 operator: addrs[0], 330 from: addrs[1], 331 ids: ids, 332 err: sdkerrors.ErrInvalidAddress, 333 }, 334 "empty ids": { 335 contractID: "deadbeef", 336 operator: addrs[0], 337 from: addrs[1], 338 to: addrs[2], 339 err: collection.ErrEmptyField, 340 }, 341 "invalid id": { 342 contractID: "deadbeef", 343 operator: addrs[0], 344 from: addrs[1], 345 to: addrs[2], 346 ids: []string{""}, 347 err: collection.ErrInvalidTokenID, 348 }, 349 } 350 351 for name, tc := range testCases { 352 t.Run(name, func(t *testing.T) { 353 msg := collection.MsgOperatorSendNFT{ 354 ContractId: tc.contractID, 355 Operator: tc.operator.String(), 356 From: tc.from.String(), 357 To: tc.to.String(), 358 TokenIds: tc.ids, 359 } 360 361 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 362 if tc.err != nil { 363 return 364 } 365 366 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 367 }) 368 } 369 } 370 371 func TestMsgAuthorizeOperator(t *testing.T) { 372 addrs := make([]sdk.AccAddress, 2) 373 for i := range addrs { 374 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 375 } 376 377 testCases := map[string]struct { 378 contractID string 379 holder sdk.AccAddress 380 operator sdk.AccAddress 381 err error 382 }{ 383 "valid msg": { 384 contractID: "deadbeef", 385 holder: addrs[0], 386 operator: addrs[1], 387 }, 388 "invalid contract id": { 389 holder: addrs[0], 390 operator: addrs[1], 391 err: class.ErrInvalidContractID, 392 }, 393 "invalid holder": { 394 contractID: "deadbeef", 395 operator: addrs[1], 396 err: sdkerrors.ErrInvalidAddress, 397 }, 398 "empty operator": { 399 contractID: "deadbeef", 400 holder: addrs[0], 401 err: sdkerrors.ErrInvalidAddress, 402 }, 403 } 404 405 for name, tc := range testCases { 406 t.Run(name, func(t *testing.T) { 407 msg := collection.MsgAuthorizeOperator{ 408 ContractId: tc.contractID, 409 Holder: tc.holder.String(), 410 Operator: tc.operator.String(), 411 } 412 413 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 414 if tc.err != nil { 415 return 416 } 417 418 require.Equal(t, []sdk.AccAddress{tc.holder}, msg.GetSigners()) 419 }) 420 } 421 } 422 423 func TestMsgRevokeOperator(t *testing.T) { 424 addrs := make([]sdk.AccAddress, 2) 425 for i := range addrs { 426 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 427 } 428 429 testCases := map[string]struct { 430 contractID string 431 holder sdk.AccAddress 432 operator sdk.AccAddress 433 err error 434 }{ 435 "valid msg": { 436 contractID: "deadbeef", 437 holder: addrs[0], 438 operator: addrs[1], 439 }, 440 "invalid contract id": { 441 holder: addrs[0], 442 operator: addrs[1], 443 err: class.ErrInvalidContractID, 444 }, 445 "invalid holder": { 446 contractID: "deadbeef", 447 operator: addrs[1], 448 err: sdkerrors.ErrInvalidAddress, 449 }, 450 "empty operator": { 451 contractID: "deadbeef", 452 holder: addrs[0], 453 err: sdkerrors.ErrInvalidAddress, 454 }, 455 } 456 457 for name, tc := range testCases { 458 t.Run(name, func(t *testing.T) { 459 msg := collection.MsgRevokeOperator{ 460 ContractId: tc.contractID, 461 Holder: tc.holder.String(), 462 Operator: tc.operator.String(), 463 } 464 465 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 466 if tc.err != nil { 467 return 468 } 469 470 require.Equal(t, []sdk.AccAddress{tc.holder}, msg.GetSigners()) 471 }) 472 } 473 } 474 475 func TestMsgCreateContract(t *testing.T) { 476 addrs := make([]sdk.AccAddress, 1) 477 for i := range addrs { 478 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 479 } 480 481 name := "tibetian fox" 482 uri := "file:///tibetian_fox.png" 483 meta := "Tibetian fox" 484 testCases := map[string]struct { 485 owner sdk.AccAddress 486 name string 487 baseImgURI string 488 meta string 489 err error 490 }{ 491 "valid msg": { 492 owner: addrs[0], 493 name: name, 494 baseImgURI: uri, 495 meta: meta, 496 }, 497 "invalid owner": { 498 name: name, 499 baseImgURI: uri, 500 meta: meta, 501 err: sdkerrors.ErrInvalidAddress, 502 }, 503 "long name": { 504 owner: addrs[0], 505 name: string(make([]rune, 21)), 506 baseImgURI: uri, 507 meta: meta, 508 err: collection.ErrInvalidNameLength, 509 }, 510 "invalid base image uri": { 511 owner: addrs[0], 512 name: name, 513 baseImgURI: string(make([]rune, 1001)), 514 meta: meta, 515 err: collection.ErrInvalidBaseImgURILength, 516 }, 517 "invalid meta": { 518 owner: addrs[0], 519 name: name, 520 baseImgURI: uri, 521 meta: string(make([]rune, 1001)), 522 err: collection.ErrInvalidMetaLength, 523 }, 524 } 525 526 for name, tc := range testCases { 527 t.Run(name, func(t *testing.T) { 528 msg := collection.MsgCreateContract{ 529 Owner: tc.owner.String(), 530 Name: tc.name, 531 Uri: tc.baseImgURI, 532 Meta: tc.meta, 533 } 534 535 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 536 if tc.err != nil { 537 return 538 } 539 540 require.Equal(t, []sdk.AccAddress{tc.owner}, msg.GetSigners()) 541 }) 542 } 543 } 544 545 func TestMsgIssueFT(t *testing.T) { 546 addrs := make([]sdk.AccAddress, 2) 547 for i := range addrs { 548 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 549 } 550 551 contractID := "deadbeef" 552 name := "tibetian fox" 553 meta := "Tibetian Fox" 554 decimals := int32(8) 555 testCases := map[string]struct { 556 contractID string 557 owner sdk.AccAddress 558 to sdk.AccAddress 559 name string 560 meta string 561 decimals int32 562 mintable bool 563 amount sdk.Int 564 err error 565 }{ 566 "valid msg": { 567 contractID: contractID, 568 owner: addrs[0], 569 to: addrs[1], 570 name: name, 571 meta: meta, 572 decimals: decimals, 573 amount: sdk.OneInt(), 574 }, 575 "invalid contract id": { 576 owner: addrs[0], 577 to: addrs[1], 578 name: name, 579 meta: meta, 580 decimals: decimals, 581 amount: sdk.OneInt(), 582 err: class.ErrInvalidContractID, 583 }, 584 "invalid owner": { 585 contractID: contractID, 586 to: addrs[1], 587 name: name, 588 meta: meta, 589 decimals: decimals, 590 amount: sdk.OneInt(), 591 err: sdkerrors.ErrInvalidAddress, 592 }, 593 "invalid to": { 594 contractID: contractID, 595 owner: addrs[0], 596 name: name, 597 meta: meta, 598 decimals: decimals, 599 amount: sdk.OneInt(), 600 err: sdkerrors.ErrInvalidAddress, 601 }, 602 "empty name": { 603 contractID: contractID, 604 owner: addrs[0], 605 to: addrs[1], 606 meta: meta, 607 decimals: decimals, 608 amount: sdk.OneInt(), 609 err: collection.ErrInvalidTokenName, 610 }, 611 "long name": { 612 contractID: contractID, 613 owner: addrs[0], 614 to: addrs[1], 615 name: string(make([]rune, 21)), 616 meta: meta, 617 decimals: decimals, 618 amount: sdk.OneInt(), 619 err: collection.ErrInvalidNameLength, 620 }, 621 "invalid meta": { 622 contractID: contractID, 623 owner: addrs[0], 624 to: addrs[1], 625 name: name, 626 meta: string(make([]rune, 1001)), 627 decimals: decimals, 628 amount: sdk.OneInt(), 629 err: collection.ErrInvalidMetaLength, 630 }, 631 "invalid decimals": { 632 contractID: contractID, 633 owner: addrs[0], 634 to: addrs[1], 635 name: name, 636 meta: meta, 637 decimals: 19, 638 amount: sdk.OneInt(), 639 err: collection.ErrInvalidTokenDecimals, 640 }, 641 "invalid decimals - negative": { 642 contractID: contractID, 643 owner: addrs[0], 644 to: addrs[1], 645 name: name, 646 meta: meta, 647 decimals: -1, 648 amount: sdk.OneInt(), 649 err: collection.ErrInvalidTokenDecimals, 650 }, 651 "daphne compat": { 652 contractID: contractID, 653 owner: addrs[0], 654 to: addrs[1], 655 name: name, 656 meta: meta, 657 amount: sdk.OneInt(), 658 err: collection.ErrInvalidIssueFT, 659 }, 660 } 661 662 for name, tc := range testCases { 663 t.Run(name, func(t *testing.T) { 664 msg := collection.MsgIssueFT{ 665 ContractId: tc.contractID, 666 Owner: tc.owner.String(), 667 To: tc.to.String(), 668 Name: tc.name, 669 Meta: tc.meta, 670 Decimals: tc.decimals, 671 Amount: tc.amount, 672 } 673 674 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 675 if tc.err != nil { 676 return 677 } 678 679 require.Equal(t, []sdk.AccAddress{tc.owner}, msg.GetSigners()) 680 }) 681 } 682 } 683 684 func TestMsgIssueNFT(t *testing.T) { 685 addrs := make([]sdk.AccAddress, 1) 686 for i := range addrs { 687 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 688 } 689 690 contractID := "deadbeef" 691 name := "tibetian fox" 692 meta := "Tibetian Fox" 693 testCases := map[string]struct { 694 contractID string 695 operator sdk.AccAddress 696 name string 697 meta string 698 err error 699 }{ 700 "valid msg": { 701 contractID: contractID, 702 operator: addrs[0], 703 name: name, 704 meta: meta, 705 }, 706 "invalid contract id": { 707 operator: addrs[0], 708 name: name, 709 meta: meta, 710 err: class.ErrInvalidContractID, 711 }, 712 "invalid operator": { 713 contractID: contractID, 714 name: name, 715 meta: meta, 716 err: sdkerrors.ErrInvalidAddress, 717 }, 718 "long name": { 719 contractID: contractID, 720 operator: addrs[0], 721 name: string(make([]rune, 21)), 722 meta: meta, 723 err: collection.ErrInvalidNameLength, 724 }, 725 "invalid meta": { 726 contractID: contractID, 727 operator: addrs[0], 728 name: name, 729 meta: string(make([]rune, 1001)), 730 err: collection.ErrInvalidMetaLength, 731 }, 732 } 733 734 for name, tc := range testCases { 735 t.Run(name, func(t *testing.T) { 736 msg := collection.MsgIssueNFT{ 737 ContractId: tc.contractID, 738 Owner: tc.operator.String(), 739 Name: tc.name, 740 Meta: tc.meta, 741 } 742 743 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 744 if tc.err != nil { 745 return 746 } 747 748 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 749 }) 750 } 751 } 752 753 func TestMsgMintFT(t *testing.T) { 754 addrs := make([]sdk.AccAddress, 2) 755 for i := range addrs { 756 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 757 } 758 759 amount := collection.NewCoins( 760 collection.NewFTCoin("00bab10c", sdk.OneInt()), 761 ) 762 763 contractID := "deadbeef" 764 testCases := map[string]struct { 765 contractID string 766 operator sdk.AccAddress 767 to sdk.AccAddress 768 amount []collection.Coin 769 err error 770 }{ 771 "valid msg": { 772 contractID: contractID, 773 operator: addrs[0], 774 to: addrs[1], 775 amount: amount, 776 }, 777 // for daphne compatible 778 "valid msg - zero amount": { 779 contractID: contractID, 780 operator: addrs[0], 781 to: addrs[1], 782 }, 783 "invalid contract id": { 784 operator: addrs[0], 785 to: addrs[1], 786 amount: amount, 787 err: class.ErrInvalidContractID, 788 }, 789 "invalid operator": { 790 contractID: contractID, 791 to: addrs[1], 792 amount: amount, 793 err: sdkerrors.ErrInvalidAddress, 794 }, 795 "invalid to": { 796 contractID: contractID, 797 operator: addrs[0], 798 amount: amount, 799 err: sdkerrors.ErrInvalidAddress, 800 }, 801 "invalid amount": { 802 contractID: contractID, 803 operator: addrs[0], 804 to: addrs[1], 805 amount: []collection.Coin{{ 806 TokenId: collection.NewFTID("00bab10c"), 807 Amount: sdk.ZeroInt(), 808 }}, 809 err: collection.ErrInvalidAmount, 810 }, 811 "invalid token id": { 812 contractID: contractID, 813 operator: addrs[0], 814 to: addrs[1], 815 amount: []collection.Coin{{ 816 Amount: sdk.OneInt(), 817 }}, 818 err: collection.ErrInvalidTokenID, 819 }, 820 } 821 822 for name, tc := range testCases { 823 t.Run(name, func(t *testing.T) { 824 msg := collection.MsgMintFT{ 825 ContractId: tc.contractID, 826 From: tc.operator.String(), 827 To: tc.to.String(), 828 Amount: tc.amount, 829 } 830 831 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 832 if tc.err != nil { 833 return 834 } 835 836 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 837 }) 838 } 839 } 840 841 func TestMsgMintNFT(t *testing.T) { 842 addrs := make([]sdk.AccAddress, 2) 843 for i := range addrs { 844 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 845 } 846 847 params := []collection.MintNFTParam{{ 848 TokenType: "deadbeef", 849 Name: "tibetian fox", 850 Meta: "Tibetian Fox", 851 }} 852 testCases := map[string]struct { 853 contractID string 854 operator sdk.AccAddress 855 to sdk.AccAddress 856 params []collection.MintNFTParam 857 err error 858 }{ 859 "valid msg": { 860 contractID: "deadbeef", 861 operator: addrs[0], 862 to: addrs[1], 863 params: params, 864 }, 865 "invalid contract id": { 866 operator: addrs[0], 867 to: addrs[1], 868 params: params, 869 err: class.ErrInvalidContractID, 870 }, 871 "invalid operator": { 872 contractID: "deadbeef", 873 to: addrs[1], 874 params: params, 875 err: sdkerrors.ErrInvalidAddress, 876 }, 877 "invalid to": { 878 contractID: "deadbeef", 879 operator: addrs[0], 880 params: params, 881 err: sdkerrors.ErrInvalidAddress, 882 }, 883 "empty params": { 884 contractID: "deadbeef", 885 operator: addrs[0], 886 to: addrs[1], 887 err: collection.ErrEmptyField, 888 }, 889 "param of invalid token type": { 890 contractID: "deadbeef", 891 operator: addrs[0], 892 to: addrs[1], 893 params: []collection.MintNFTParam{{ 894 Name: "tibetian fox", 895 }}, 896 err: collection.ErrInvalidTokenType, 897 }, 898 "param of empty name": { 899 contractID: "deadbeef", 900 operator: addrs[0], 901 to: addrs[1], 902 params: []collection.MintNFTParam{{ 903 TokenType: "deadbeef", 904 }}, 905 err: collection.ErrInvalidTokenName, 906 }, 907 "param of too long name": { 908 contractID: "deadbeef", 909 operator: addrs[0], 910 to: addrs[1], 911 params: []collection.MintNFTParam{{ 912 TokenType: "deadbeef", 913 Name: string(make([]rune, 21)), 914 }}, 915 err: collection.ErrInvalidNameLength, 916 }, 917 "param of invalid meta": { 918 contractID: "deadbeef", 919 operator: addrs[0], 920 to: addrs[1], 921 params: []collection.MintNFTParam{{ 922 TokenType: "deadbeef", 923 Name: "tibetian fox", 924 Meta: string(make([]rune, 1001)), 925 }}, 926 err: collection.ErrInvalidMetaLength, 927 }, 928 } 929 930 for name, tc := range testCases { 931 t.Run(name, func(t *testing.T) { 932 msg := collection.MsgMintNFT{ 933 ContractId: tc.contractID, 934 From: tc.operator.String(), 935 To: tc.to.String(), 936 Params: tc.params, 937 } 938 939 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 940 if tc.err != nil { 941 return 942 } 943 944 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 945 }) 946 } 947 } 948 949 func TestMsgBurnFT(t *testing.T) { 950 addrs := make([]sdk.AccAddress, 1) 951 for i := range addrs { 952 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 953 } 954 955 amount := collection.NewCoins( 956 collection.NewFTCoin("00bab10c", sdk.OneInt()), 957 ) 958 959 testCases := map[string]struct { 960 contractID string 961 from sdk.AccAddress 962 amount []collection.Coin 963 err error 964 }{ 965 "valid msg": { 966 contractID: "deadbeef", 967 from: addrs[0], 968 amount: amount, 969 }, 970 // for daphne compatible 971 "valid msg - zero amount": { 972 contractID: "deadbeef", 973 from: addrs[0], 974 }, 975 "invalid contract id": { 976 from: addrs[0], 977 amount: amount, 978 err: class.ErrInvalidContractID, 979 }, 980 "invalid from": { 981 contractID: "deadbeef", 982 amount: amount, 983 err: sdkerrors.ErrInvalidAddress, 984 }, 985 "invalid token id": { 986 contractID: "deadbeef", 987 from: addrs[0], 988 amount: []collection.Coin{{ 989 Amount: sdk.OneInt(), 990 }}, 991 err: collection.ErrInvalidTokenID, 992 }, 993 "invalid amount": { 994 contractID: "deadbeef", 995 from: addrs[0], 996 amount: []collection.Coin{{ 997 TokenId: collection.NewFTID("00bab10c"), 998 Amount: sdk.ZeroInt(), 999 }}, 1000 err: collection.ErrInvalidAmount, 1001 }, 1002 } 1003 1004 for name, tc := range testCases { 1005 t.Run(name, func(t *testing.T) { 1006 msg := collection.MsgBurnFT{ 1007 ContractId: tc.contractID, 1008 From: tc.from.String(), 1009 Amount: tc.amount, 1010 } 1011 1012 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1013 if tc.err != nil { 1014 return 1015 } 1016 1017 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 1018 }) 1019 } 1020 } 1021 1022 func TestMsgOperatorBurnFT(t *testing.T) { 1023 addrs := make([]sdk.AccAddress, 2) 1024 for i := range addrs { 1025 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1026 } 1027 1028 amount := collection.NewCoins( 1029 collection.NewFTCoin("00bab10c", sdk.OneInt()), 1030 ) 1031 1032 testCases := map[string]struct { 1033 contractID string 1034 grantee sdk.AccAddress 1035 from sdk.AccAddress 1036 amount []collection.Coin 1037 err error 1038 }{ 1039 "valid msg": { 1040 contractID: "deadbeef", 1041 grantee: addrs[0], 1042 from: addrs[1], 1043 amount: amount, 1044 }, 1045 "invalid contract id": { 1046 grantee: addrs[0], 1047 from: addrs[1], 1048 amount: amount, 1049 err: class.ErrInvalidContractID, 1050 }, 1051 "invalid grantee": { 1052 contractID: "deadbeef", 1053 from: addrs[1], 1054 amount: amount, 1055 err: sdkerrors.ErrInvalidAddress, 1056 }, 1057 "invalid from": { 1058 contractID: "deadbeef", 1059 grantee: addrs[0], 1060 amount: amount, 1061 err: sdkerrors.ErrInvalidAddress, 1062 }, 1063 "invalid token id": { 1064 contractID: "deadbeef", 1065 grantee: addrs[0], 1066 from: addrs[1], 1067 amount: []collection.Coin{{ 1068 Amount: sdk.OneInt(), 1069 }}, 1070 err: collection.ErrInvalidTokenID, 1071 }, 1072 "invalid amount": { 1073 contractID: "deadbeef", 1074 grantee: addrs[0], 1075 from: addrs[1], 1076 amount: []collection.Coin{{ 1077 TokenId: collection.NewFTID("00bab10c"), 1078 Amount: sdk.ZeroInt(), 1079 }}, 1080 err: collection.ErrInvalidAmount, 1081 }, 1082 } 1083 1084 for name, tc := range testCases { 1085 t.Run(name, func(t *testing.T) { 1086 msg := collection.MsgOperatorBurnFT{ 1087 ContractId: tc.contractID, 1088 Operator: tc.grantee.String(), 1089 From: tc.from.String(), 1090 Amount: tc.amount, 1091 } 1092 1093 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1094 if tc.err != nil { 1095 return 1096 } 1097 1098 require.Equal(t, []sdk.AccAddress{tc.grantee}, msg.GetSigners()) 1099 }) 1100 } 1101 } 1102 1103 func TestMsgBurnNFT(t *testing.T) { 1104 addrs := make([]sdk.AccAddress, 1) 1105 for i := range addrs { 1106 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1107 } 1108 1109 ids := []string{collection.NewNFTID("deadbeef", 1)} 1110 1111 testCases := map[string]struct { 1112 contractID string 1113 from sdk.AccAddress 1114 ids []string 1115 err error 1116 }{ 1117 "valid msg": { 1118 contractID: "deadbeef", 1119 from: addrs[0], 1120 ids: ids, 1121 }, 1122 "invalid contract id": { 1123 from: addrs[0], 1124 ids: ids, 1125 err: class.ErrInvalidContractID, 1126 }, 1127 "invalid from": { 1128 contractID: "deadbeef", 1129 ids: ids, 1130 err: sdkerrors.ErrInvalidAddress, 1131 }, 1132 "empty ids": { 1133 contractID: "deadbeef", 1134 from: addrs[0], 1135 err: collection.ErrEmptyField, 1136 }, 1137 "invalid id": { 1138 contractID: "deadbeef", 1139 from: addrs[0], 1140 ids: []string{""}, 1141 err: collection.ErrInvalidTokenID, 1142 }, 1143 } 1144 1145 for name, tc := range testCases { 1146 t.Run(name, func(t *testing.T) { 1147 msg := collection.MsgBurnNFT{ 1148 ContractId: tc.contractID, 1149 From: tc.from.String(), 1150 TokenIds: tc.ids, 1151 } 1152 1153 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1154 if tc.err != nil { 1155 return 1156 } 1157 1158 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 1159 }) 1160 } 1161 } 1162 1163 func TestMsgOperatorBurnNFT(t *testing.T) { 1164 addrs := make([]sdk.AccAddress, 2) 1165 for i := range addrs { 1166 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1167 } 1168 1169 ids := []string{collection.NewNFTID("deadbeef", 1)} 1170 1171 testCases := map[string]struct { 1172 contractID string 1173 grantee sdk.AccAddress 1174 from sdk.AccAddress 1175 ids []string 1176 err error 1177 }{ 1178 "valid msg": { 1179 contractID: "deadbeef", 1180 grantee: addrs[0], 1181 from: addrs[1], 1182 ids: ids, 1183 }, 1184 "invalid contract id": { 1185 grantee: addrs[0], 1186 from: addrs[1], 1187 ids: ids, 1188 err: class.ErrInvalidContractID, 1189 }, 1190 "invalid grantee": { 1191 contractID: "deadbeef", 1192 from: addrs[1], 1193 ids: ids, 1194 err: sdkerrors.ErrInvalidAddress, 1195 }, 1196 "invalid from": { 1197 contractID: "deadbeef", 1198 grantee: addrs[0], 1199 ids: ids, 1200 err: sdkerrors.ErrInvalidAddress, 1201 }, 1202 "empty ids": { 1203 contractID: "deadbeef", 1204 grantee: addrs[0], 1205 from: addrs[1], 1206 err: collection.ErrEmptyField, 1207 }, 1208 "invalid id": { 1209 contractID: "deadbeef", 1210 grantee: addrs[0], 1211 from: addrs[0], 1212 ids: []string{""}, 1213 err: collection.ErrInvalidTokenID, 1214 }, 1215 } 1216 1217 for name, tc := range testCases { 1218 t.Run(name, func(t *testing.T) { 1219 msg := collection.MsgOperatorBurnNFT{ 1220 ContractId: tc.contractID, 1221 Operator: tc.grantee.String(), 1222 From: tc.from.String(), 1223 TokenIds: tc.ids, 1224 } 1225 1226 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1227 if tc.err != nil { 1228 return 1229 } 1230 1231 require.Equal(t, []sdk.AccAddress{tc.grantee}, msg.GetSigners()) 1232 }) 1233 } 1234 } 1235 1236 func TestMsgModify(t *testing.T) { 1237 addrs := make([]sdk.AccAddress, 1) 1238 for i := range addrs { 1239 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1240 } 1241 1242 changes := []collection.Attribute{{Key: collection.AttributeKeyName.String(), Value: "New test"}} 1243 testCases := map[string]struct { 1244 contractID string 1245 owner sdk.AccAddress 1246 tokenType string 1247 tokenIndex string 1248 changes []collection.Attribute 1249 err error 1250 }{ 1251 "valid contract modification": { 1252 contractID: "deadbeef", 1253 owner: addrs[0], 1254 changes: changes, 1255 }, 1256 "valid token class modification": { 1257 contractID: "deadbeef", 1258 tokenType: "deadbeef", 1259 owner: addrs[0], 1260 changes: changes, 1261 }, 1262 "invalid nft class modification": { 1263 contractID: "deadbeef", 1264 tokenType: "deadbeef", 1265 tokenIndex: "00000000", 1266 owner: addrs[0], 1267 changes: changes, 1268 err: collection.ErrInvalidTokenIndex, 1269 }, 1270 "valid nft modification": { 1271 contractID: "deadbeef", 1272 tokenType: "deadbeef", 1273 tokenIndex: "deadbeef", 1274 owner: addrs[0], 1275 changes: changes, 1276 }, 1277 "invalid contract id": { 1278 owner: addrs[0], 1279 changes: changes, 1280 err: class.ErrInvalidContractID, 1281 }, 1282 "invalid owner": { 1283 contractID: "deadbeef", 1284 changes: changes, 1285 err: sdkerrors.ErrInvalidAddress, 1286 }, 1287 "invalid key of change": { 1288 contractID: "deadbeef", 1289 owner: addrs[0], 1290 changes: []collection.Attribute{{Key: strings.ToUpper(collection.AttributeKeyName.String()), Value: "tt"}}, 1291 err: collection.ErrInvalidChangesField, 1292 }, 1293 "invalid value of change": { 1294 contractID: "deadbeef", 1295 owner: addrs[0], 1296 changes: []collection.Attribute{{Key: collection.AttributeKeyName.String(), Value: string(make([]rune, 21))}}, 1297 err: collection.ErrInvalidNameLength, 1298 }, 1299 "empty changes": { 1300 contractID: "deadbeef", 1301 owner: addrs[0], 1302 err: collection.ErrEmptyChanges, 1303 }, 1304 "too many changes": { 1305 contractID: "deadbeef", 1306 owner: addrs[0], 1307 changes: make([]collection.Attribute, 101), 1308 err: collection.ErrInvalidChangesFieldCount, 1309 }, 1310 "duplicated changes": { 1311 contractID: "deadbeef", 1312 owner: addrs[0], 1313 changes: []collection.Attribute{ 1314 {Key: collection.AttributeKeyBaseImgURI.String(), Value: "hello"}, 1315 {Key: collection.AttributeKeyURI.String(), Value: "world"}, 1316 }, 1317 err: collection.ErrDuplicateChangesField, 1318 }, 1319 } 1320 1321 for name, tc := range testCases { 1322 t.Run(name, func(t *testing.T) { 1323 msg := collection.MsgModify{ 1324 ContractId: tc.contractID, 1325 TokenType: tc.tokenType, 1326 TokenIndex: tc.tokenIndex, 1327 Owner: tc.owner.String(), 1328 Changes: tc.changes, 1329 } 1330 1331 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1332 if tc.err != nil { 1333 return 1334 } 1335 1336 require.Equal(t, []sdk.AccAddress{tc.owner}, msg.GetSigners()) 1337 }) 1338 } 1339 } 1340 1341 func TestMsgGrantPermission(t *testing.T) { 1342 addrs := make([]sdk.AccAddress, 2) 1343 for i := range addrs { 1344 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1345 } 1346 1347 testCases := map[string]struct { 1348 contractID string 1349 from sdk.AccAddress 1350 to sdk.AccAddress 1351 permission string 1352 err error 1353 }{ 1354 "valid msg": { 1355 contractID: "deadbeef", 1356 from: addrs[0], 1357 to: addrs[1], 1358 permission: collection.LegacyPermissionMint.String(), 1359 }, 1360 "invalid contract id": { 1361 from: addrs[0], 1362 to: addrs[1], 1363 permission: collection.LegacyPermissionMint.String(), 1364 err: class.ErrInvalidContractID, 1365 }, 1366 "invalid from": { 1367 contractID: "deadbeef", 1368 to: addrs[1], 1369 permission: collection.LegacyPermissionMint.String(), 1370 err: sdkerrors.ErrInvalidAddress, 1371 }, 1372 "invalid to": { 1373 contractID: "deadbeef", 1374 from: addrs[0], 1375 permission: collection.LegacyPermissionMint.String(), 1376 err: sdkerrors.ErrInvalidAddress, 1377 }, 1378 "invalid permission": { 1379 contractID: "deadbeef", 1380 from: addrs[0], 1381 to: addrs[1], 1382 err: sdkerrors.ErrInvalidPermission, 1383 }, 1384 } 1385 1386 for name, tc := range testCases { 1387 t.Run(name, func(t *testing.T) { 1388 msg := collection.MsgGrantPermission{ 1389 ContractId: tc.contractID, 1390 From: tc.from.String(), 1391 To: tc.to.String(), 1392 Permission: tc.permission, 1393 } 1394 1395 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1396 if tc.err != nil { 1397 return 1398 } 1399 1400 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 1401 }) 1402 } 1403 } 1404 1405 func TestMsgRevokePermission(t *testing.T) { 1406 addrs := make([]sdk.AccAddress, 1) 1407 for i := range addrs { 1408 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1409 } 1410 1411 testCases := map[string]struct { 1412 contractID string 1413 from sdk.AccAddress 1414 permission string 1415 err error 1416 }{ 1417 "valid msg": { 1418 contractID: "deadbeef", 1419 from: addrs[0], 1420 permission: collection.LegacyPermissionMint.String(), 1421 }, 1422 "invalid contract id": { 1423 from: addrs[0], 1424 permission: collection.LegacyPermissionMint.String(), 1425 err: class.ErrInvalidContractID, 1426 }, 1427 "invalid from": { 1428 contractID: "deadbeef", 1429 permission: collection.LegacyPermissionMint.String(), 1430 err: sdkerrors.ErrInvalidAddress, 1431 }, 1432 "invalid permission": { 1433 contractID: "deadbeef", 1434 from: addrs[0], 1435 err: sdkerrors.ErrInvalidPermission, 1436 }, 1437 } 1438 1439 for name, tc := range testCases { 1440 t.Run(name, func(t *testing.T) { 1441 msg := collection.MsgRevokePermission{ 1442 ContractId: tc.contractID, 1443 From: tc.from.String(), 1444 Permission: tc.permission, 1445 } 1446 1447 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1448 if tc.err != nil { 1449 return 1450 } 1451 1452 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 1453 }) 1454 } 1455 } 1456 1457 func TestMsgAttach(t *testing.T) { 1458 addrs := make([]sdk.AccAddress, 1) 1459 for i := range addrs { 1460 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1461 } 1462 1463 contractID := "deadbeef" 1464 tokenIDs := []string{ 1465 collection.NewNFTID("deadbeef", 1), 1466 collection.NewNFTID("fee1dead", 1), 1467 } 1468 1469 testCases := map[string]struct { 1470 contractID string 1471 from sdk.AccAddress 1472 tokenID string 1473 toTokenID string 1474 err error 1475 }{ 1476 "valid msg": { 1477 contractID: contractID, 1478 from: addrs[0], 1479 tokenID: tokenIDs[0], 1480 toTokenID: tokenIDs[1], 1481 }, 1482 "invalid from": { 1483 contractID: contractID, 1484 tokenID: tokenIDs[0], 1485 toTokenID: tokenIDs[1], 1486 err: sdkerrors.ErrInvalidAddress, 1487 }, 1488 "invalid contract id": { 1489 from: addrs[0], 1490 tokenID: tokenIDs[0], 1491 toTokenID: tokenIDs[1], 1492 err: class.ErrInvalidContractID, 1493 }, 1494 "invalid token id": { 1495 contractID: contractID, 1496 from: addrs[0], 1497 toTokenID: tokenIDs[1], 1498 err: collection.ErrInvalidTokenID, 1499 }, 1500 "invalid to id": { 1501 contractID: contractID, 1502 from: addrs[0], 1503 tokenID: tokenIDs[0], 1504 err: collection.ErrInvalidTokenID, 1505 }, 1506 "to itself": { 1507 contractID: contractID, 1508 from: addrs[0], 1509 tokenID: tokenIDs[0], 1510 toTokenID: tokenIDs[0], 1511 err: collection.ErrCannotAttachToItself, 1512 }, 1513 } 1514 1515 for name, tc := range testCases { 1516 t.Run(name, func(t *testing.T) { 1517 msg := collection.MsgAttach{ 1518 ContractId: tc.contractID, 1519 From: tc.from.String(), 1520 TokenId: tc.tokenID, 1521 ToTokenId: tc.toTokenID, 1522 } 1523 1524 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1525 if tc.err != nil { 1526 return 1527 } 1528 1529 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 1530 }) 1531 } 1532 } 1533 1534 func TestMsgDetach(t *testing.T) { 1535 addrs := make([]sdk.AccAddress, 1) 1536 for i := range addrs { 1537 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1538 } 1539 1540 contractID := "deadbeef" 1541 tokenID := collection.NewNFTID("deadbeef", 1) 1542 1543 testCases := map[string]struct { 1544 contractID string 1545 from sdk.AccAddress 1546 tokenID string 1547 err error 1548 }{ 1549 "valid msg": { 1550 contractID: contractID, 1551 from: addrs[0], 1552 tokenID: tokenID, 1553 }, 1554 "invalid from": { 1555 contractID: contractID, 1556 tokenID: tokenID, 1557 err: sdkerrors.ErrInvalidAddress, 1558 }, 1559 "invalid contract id": { 1560 from: addrs[0], 1561 tokenID: tokenID, 1562 err: class.ErrInvalidContractID, 1563 }, 1564 "invalid token id": { 1565 contractID: contractID, 1566 from: addrs[0], 1567 err: collection.ErrInvalidTokenID, 1568 }, 1569 } 1570 1571 for name, tc := range testCases { 1572 t.Run(name, func(t *testing.T) { 1573 msg := collection.MsgDetach{ 1574 ContractId: tc.contractID, 1575 From: tc.from.String(), 1576 TokenId: tc.tokenID, 1577 } 1578 1579 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1580 if tc.err != nil { 1581 return 1582 } 1583 1584 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 1585 }) 1586 } 1587 } 1588 1589 func TestMsgOperatorAttach(t *testing.T) { 1590 addrs := make([]sdk.AccAddress, 2) 1591 for i := range addrs { 1592 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1593 } 1594 1595 tokenIDs := []string{ 1596 collection.NewNFTID("deadbeef", 1), 1597 collection.NewNFTID("fee1dead", 1), 1598 } 1599 1600 testCases := map[string]struct { 1601 contractID string 1602 operator sdk.AccAddress 1603 from sdk.AccAddress 1604 tokenID string 1605 toTokenID string 1606 err error 1607 }{ 1608 "valid msg": { 1609 contractID: "deadbeef", 1610 operator: addrs[0], 1611 from: addrs[1], 1612 tokenID: tokenIDs[0], 1613 toTokenID: tokenIDs[1], 1614 }, 1615 "empty operator": { 1616 contractID: "deadbeef", 1617 from: addrs[1], 1618 tokenID: tokenIDs[0], 1619 toTokenID: tokenIDs[1], 1620 err: sdkerrors.ErrInvalidAddress, 1621 }, 1622 "invalid from": { 1623 contractID: "deadbeef", 1624 operator: addrs[0], 1625 tokenID: tokenIDs[0], 1626 toTokenID: tokenIDs[1], 1627 err: sdkerrors.ErrInvalidAddress, 1628 }, 1629 "invalid contract id": { 1630 operator: addrs[0], 1631 from: addrs[1], 1632 tokenID: tokenIDs[0], 1633 toTokenID: tokenIDs[1], 1634 err: class.ErrInvalidContractID, 1635 }, 1636 "invalid token id": { 1637 contractID: "deadbeef", 1638 operator: addrs[0], 1639 from: addrs[1], 1640 toTokenID: tokenIDs[1], 1641 err: collection.ErrInvalidTokenID, 1642 }, 1643 "invalid to id": { 1644 contractID: "deadbeef", 1645 operator: addrs[0], 1646 from: addrs[1], 1647 tokenID: tokenIDs[0], 1648 err: collection.ErrInvalidTokenID, 1649 }, 1650 "to itself": { 1651 contractID: "deadbeef", 1652 operator: addrs[0], 1653 from: addrs[1], 1654 tokenID: tokenIDs[0], 1655 toTokenID: tokenIDs[0], 1656 err: collection.ErrCannotAttachToItself, 1657 }, 1658 } 1659 1660 for name, tc := range testCases { 1661 t.Run(name, func(t *testing.T) { 1662 msg := collection.MsgOperatorAttach{ 1663 ContractId: tc.contractID, 1664 Operator: tc.operator.String(), 1665 From: tc.from.String(), 1666 TokenId: tc.tokenID, 1667 ToTokenId: tc.toTokenID, 1668 } 1669 1670 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1671 if tc.err != nil { 1672 return 1673 } 1674 1675 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 1676 }) 1677 } 1678 } 1679 1680 func TestMsgOperatorDetach(t *testing.T) { 1681 addrs := make([]sdk.AccAddress, 2) 1682 for i := range addrs { 1683 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1684 } 1685 1686 tokenID := collection.NewNFTID("deadbeef", 1) 1687 1688 testCases := map[string]struct { 1689 contractID string 1690 operator sdk.AccAddress 1691 from sdk.AccAddress 1692 tokenID string 1693 err error 1694 }{ 1695 "valid msg": { 1696 contractID: "deadbeef", 1697 operator: addrs[0], 1698 from: addrs[1], 1699 tokenID: tokenID, 1700 }, 1701 "empty operator": { 1702 contractID: "deadbeef", 1703 from: addrs[1], 1704 tokenID: tokenID, 1705 err: sdkerrors.ErrInvalidAddress, 1706 }, 1707 "invalid from": { 1708 contractID: "deadbeef", 1709 operator: addrs[0], 1710 tokenID: tokenID, 1711 err: sdkerrors.ErrInvalidAddress, 1712 }, 1713 "invalid contract id": { 1714 operator: addrs[0], 1715 from: addrs[1], 1716 tokenID: tokenID, 1717 err: class.ErrInvalidContractID, 1718 }, 1719 "invalid token id": { 1720 contractID: "deadbeef", 1721 operator: addrs[0], 1722 from: addrs[1], 1723 err: collection.ErrInvalidTokenID, 1724 }, 1725 } 1726 1727 for name, tc := range testCases { 1728 t.Run(name, func(t *testing.T) { 1729 msg := collection.MsgOperatorDetach{ 1730 ContractId: tc.contractID, 1731 Operator: tc.operator.String(), 1732 From: tc.from.String(), 1733 TokenId: tc.tokenID, 1734 } 1735 1736 require.ErrorIs(t, msg.ValidateBasic(), tc.err) 1737 if tc.err != nil { 1738 return 1739 } 1740 1741 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 1742 }) 1743 } 1744 } 1745 1746 func TestAminoJSON(t *testing.T) { 1747 tx := legacytx.StdTx{} 1748 var contractId = "deadbeef" 1749 var ftClassId = "00bab10c" 1750 1751 addrs := make([]sdk.AccAddress, 3) 1752 for i := range addrs { 1753 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 1754 } 1755 1756 ftAmount := collection.NewCoins(collection.NewFTCoin(ftClassId, sdk.NewInt(1000000))) 1757 tokenIds := []string{collection.NewNFTID(contractId, 1)} 1758 nftParams := []collection.MintNFTParam{{ 1759 TokenType: "deadbeef", 1760 Name: "tibetian fox", 1761 Meta: "Tibetian Fox", 1762 }} 1763 1764 testCase := map[string]struct { 1765 msg legacytx.LegacyMsg 1766 expectedType string 1767 expected string 1768 }{ 1769 "MsgSendFT": { 1770 &collection.MsgSendFT{ 1771 ContractId: contractId, 1772 From: addrs[0].String(), 1773 To: addrs[1].String(), 1774 Amount: ftAmount, 1775 }, 1776 "/lbm.collection.v1.MsgSendFT", 1777 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSendFT\",\"value\":{\"amount\":[{\"amount\":\"1000000\",\"token_id\":\"00bab10c00000000\"}],\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1778 }, 1779 "MsgOperatorSendFT": { 1780 &collection.MsgOperatorSendFT{ 1781 ContractId: contractId, 1782 Operator: addrs[0].String(), 1783 From: addrs[1].String(), 1784 To: addrs[2].String(), 1785 Amount: ftAmount, 1786 }, 1787 "/lbm.collection.v1.MsgOperatorSendFT", 1788 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorSendFT\",\"value\":{\"amount\":[{\"amount\":\"1000000\",\"token_id\":\"00bab10c00000000\"}],\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String(), addrs[2].String()), 1789 }, 1790 "MsgSendNFT": { 1791 &collection.MsgSendNFT{ 1792 ContractId: contractId, 1793 From: addrs[0].String(), 1794 To: addrs[1].String(), 1795 TokenIds: tokenIds, 1796 }, 1797 "/lbm.collection.v1.MsgSendNFT", 1798 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSendNFT\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"to\":\"%s\",\"token_ids\":[\"deadbeef00000001\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1799 }, 1800 "MsgOperatorSendNFT": { 1801 &collection.MsgOperatorSendNFT{ 1802 ContractId: contractId, 1803 Operator: addrs[0].String(), 1804 From: addrs[1].String(), 1805 To: addrs[2].String(), 1806 TokenIds: tokenIds, 1807 }, 1808 "/lbm.collection.v1.MsgOperatorSendNFT", 1809 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorSendNFT\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\",\"to\":\"%s\",\"token_ids\":[\"deadbeef00000001\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String(), addrs[2].String()), 1810 }, 1811 "MsgAuthorizeOperator": { 1812 &collection.MsgAuthorizeOperator{ 1813 ContractId: contractId, 1814 Holder: addrs[0].String(), 1815 Operator: addrs[1].String(), 1816 }, 1817 "/lbm.collection.v1.MsgAuthorizeOperator", 1818 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/collection/MsgAuthorizeOperator\",\"value\":{\"contract_id\":\"deadbeef\",\"holder\":\"%s\",\"operator\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1819 }, 1820 "MsgRevokeOperator": { 1821 &collection.MsgRevokeOperator{ 1822 ContractId: contractId, 1823 Holder: addrs[0].String(), 1824 Operator: addrs[1].String(), 1825 }, 1826 "/lbm.collection.v1.MsgRevokeOperator", 1827 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/collection/MsgRevokeOperator\",\"value\":{\"contract_id\":\"deadbeef\",\"holder\":\"%s\",\"operator\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1828 }, 1829 "MsgCreateContract": { 1830 &collection.MsgCreateContract{ 1831 Owner: addrs[0].String(), 1832 Name: "Test Contract", 1833 Uri: "http://image.url", 1834 Meta: "This is test", 1835 }, 1836 "/lbm.collection.v1.MsgCreateContract", 1837 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgCreateContract\",\"value\":{\"meta\":\"This is test\",\"name\":\"Test Contract\",\"owner\":\"%s\",\"uri\":\"http://image.url\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1838 }, 1839 "MsgIssueFT": { 1840 &collection.MsgIssueFT{ 1841 ContractId: contractId, 1842 Name: "Test FT", 1843 Meta: "This is FT Meta", 1844 Decimals: 6, 1845 Mintable: false, 1846 Owner: addrs[0].String(), 1847 To: addrs[1].String(), 1848 Amount: sdk.NewInt(1000000), 1849 }, 1850 "/lbm.collection.v1.MsgIssueFT", 1851 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgIssueFT\",\"value\":{\"amount\":\"1000000\",\"contract_id\":\"deadbeef\",\"decimals\":6,\"meta\":\"This is FT Meta\",\"name\":\"Test FT\",\"owner\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1852 }, 1853 "MsgIssueNFT": { 1854 &collection.MsgIssueNFT{ 1855 ContractId: contractId, 1856 Name: "Test NFT", 1857 Meta: "This is NFT Meta", 1858 Owner: addrs[0].String(), 1859 }, 1860 "/lbm.collection.v1.MsgIssueNFT", 1861 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgIssueNFT\",\"value\":{\"contract_id\":\"deadbeef\",\"meta\":\"This is NFT Meta\",\"name\":\"Test NFT\",\"owner\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1862 }, 1863 "MsgMintFT": { 1864 &collection.MsgMintFT{ 1865 ContractId: contractId, 1866 From: addrs[0].String(), 1867 To: addrs[1].String(), 1868 Amount: ftAmount, 1869 }, 1870 "/lbm.collection.v1.MsgMintFT", 1871 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgMintFT\",\"value\":{\"amount\":[{\"amount\":\"1000000\",\"token_id\":\"00bab10c00000000\"}],\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1872 }, 1873 "MsgMintNFT": { 1874 &collection.MsgMintNFT{ 1875 ContractId: contractId, 1876 From: addrs[0].String(), 1877 To: addrs[1].String(), 1878 Params: nftParams, 1879 }, 1880 "/lbm.collection.v1.MsgMintNFT", 1881 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgMintNFT\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"params\":[{\"meta\":\"Tibetian Fox\",\"name\":\"tibetian fox\",\"token_type\":\"deadbeef\"}],\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1882 }, 1883 "MsgBurnFT": { 1884 &collection.MsgBurnFT{ 1885 ContractId: contractId, 1886 From: addrs[0].String(), 1887 Amount: ftAmount, 1888 }, 1889 "/lbm.collection.v1.MsgBurnFT", 1890 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgBurnFT\",\"value\":{\"amount\":[{\"amount\":\"1000000\",\"token_id\":\"00bab10c00000000\"}],\"contract_id\":\"deadbeef\",\"from\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1891 }, 1892 "MsgOperatorBurnFT": { 1893 &collection.MsgOperatorBurnFT{ 1894 ContractId: contractId, 1895 Operator: addrs[0].String(), 1896 From: addrs[1].String(), 1897 Amount: ftAmount, 1898 }, 1899 "/lbm.collection.v1.MsgOperatorBurnFT", 1900 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorBurnFT\",\"value\":{\"amount\":[{\"amount\":\"1000000\",\"token_id\":\"00bab10c00000000\"}],\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String()), 1901 }, 1902 "MsgBurnNFT": { 1903 &collection.MsgBurnNFT{ 1904 ContractId: contractId, 1905 From: addrs[0].String(), 1906 TokenIds: tokenIds, 1907 }, 1908 "/lbm.collection.v1.MsgBurnNFT", 1909 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgBurnNFT\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"token_ids\":[\"deadbeef00000001\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1910 }, 1911 "MsgOperatorBurnNFT": { 1912 &collection.MsgOperatorBurnNFT{ 1913 ContractId: contractId, 1914 Operator: addrs[0].String(), 1915 From: addrs[1].String(), 1916 TokenIds: tokenIds, 1917 }, 1918 "/lbm.collection.v1.MsgOperatorBurnNFT", 1919 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorBurnNFT\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\",\"token_ids\":[\"deadbeef00000001\"]}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String()), 1920 }, 1921 "MsgModify": { 1922 &collection.MsgModify{ 1923 ContractId: contractId, 1924 Owner: addrs[0].String(), 1925 TokenType: "NewType", 1926 TokenIndex: "deadbeef", 1927 Changes: []collection.Attribute{{Key: "name", Value: "New test"}}, 1928 }, 1929 "/lbm.collection.v1.MsgModify", 1930 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/collection/MsgModify\",\"value\":{\"changes\":[{\"key\":\"name\",\"value\":\"New test\"}],\"contract_id\":\"deadbeef\",\"owner\":\"%s\",\"token_index\":\"deadbeef\",\"token_type\":\"NewType\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1931 }, 1932 "MsgGrantPermission": { 1933 &collection.MsgGrantPermission{ 1934 ContractId: contractId, 1935 From: addrs[0].String(), 1936 To: addrs[1].String(), 1937 Permission: collection.LegacyPermissionMint.String(), 1938 }, 1939 "/lbm.collection.v1.MsgGrantPermission", 1940 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/collection/MsgGrantPermission\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"permission\":\"mint\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 1941 }, 1942 "MsgRevokePermission": { 1943 &collection.MsgRevokePermission{ 1944 ContractId: contractId, 1945 From: addrs[0].String(), 1946 Permission: collection.LegacyPermissionMint.String(), 1947 }, 1948 "/lbm.collection.v1.MsgRevokePermission", 1949 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/collection/MsgRevokePermission\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"permission\":\"mint\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1950 }, 1951 "MsgAttach": { 1952 &collection.MsgAttach{ 1953 ContractId: contractId, 1954 From: addrs[0].String(), 1955 TokenId: collection.NewNFTID("deadbeef", 1), 1956 ToTokenId: collection.NewNFTID("fee1dead", 1), 1957 }, 1958 "/lbm.collection.v1.MsgAttach", 1959 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgAttach\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"to_token_id\":\"fee1dead00000001\",\"token_id\":\"deadbeef00000001\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1960 }, 1961 "MsgDetach": { 1962 &collection.MsgDetach{ 1963 ContractId: contractId, 1964 From: addrs[0].String(), 1965 TokenId: collection.NewNFTID("fee1dead", 1), 1966 }, 1967 "/lbm.collection.v1.MsgDetach", 1968 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgDetach\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"token_id\":\"fee1dead00000001\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1969 }, 1970 "MsgOperatorAttach": { 1971 &collection.MsgOperatorAttach{ 1972 ContractId: contractId, 1973 Operator: addrs[0].String(), 1974 From: addrs[1].String(), 1975 TokenId: collection.NewNFTID("deadbeef", 1), 1976 ToTokenId: collection.NewNFTID("fee1dead", 1), 1977 }, 1978 "/lbm.collection.v1.MsgOperatorAttach", 1979 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorAttach\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\",\"to_token_id\":\"fee1dead00000001\",\"token_id\":\"deadbeef00000001\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String()), 1980 }, 1981 "MsgOperatorDetach": { 1982 &collection.MsgOperatorDetach{ 1983 ContractId: contractId, 1984 Operator: addrs[0].String(), 1985 From: addrs[1].String(), 1986 TokenId: collection.NewNFTID("fee1dead", 1), 1987 }, 1988 "/lbm.collection.v1.MsgOperatorDetach", 1989 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorDetach\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\",\"token_id\":\"fee1dead00000001\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String()), 1990 }, 1991 } 1992 1993 for name, tc := range testCase { 1994 tc := tc 1995 t.Run(name, func(t *testing.T) { 1996 tx.Msgs = []sdk.Msg{tc.msg} 1997 require.Equal(t, collection.RouterKey, tc.msg.Route()) 1998 require.Equal(t, tc.expectedType, tc.msg.Type()) 1999 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{tc.msg}, "memo"))) 2000 }) 2001 } 2002 }