github.com/Finschia/finschia-sdk@v0.49.1/x/token/msgs_test.go (about) 1 package token_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/token" 15 "github.com/Finschia/finschia-sdk/x/token/class" 16 ) 17 18 func TestMsgSend(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 testCases := map[string]struct { 25 contractID string 26 from sdk.AccAddress 27 to sdk.AccAddress 28 amount sdk.Int 29 err error 30 }{ 31 "valid msg": { 32 contractID: "deadbeef", 33 from: addrs[0], 34 to: addrs[1], 35 amount: sdk.OneInt(), 36 }, 37 "invalid from": { 38 contractID: "deadbeef", 39 to: addrs[1], 40 amount: sdk.OneInt(), 41 err: sdkerrors.ErrInvalidAddress, 42 }, 43 "invalid contract id": { 44 from: addrs[0], 45 to: addrs[1], 46 amount: sdk.OneInt(), 47 err: class.ErrInvalidContractID, 48 }, 49 "invalid to": { 50 contractID: "deadbeef", 51 from: addrs[0], 52 amount: sdk.OneInt(), 53 err: sdkerrors.ErrInvalidAddress, 54 }, 55 "invalid amount": { 56 contractID: "deadbeef", 57 from: addrs[0], 58 to: addrs[1], 59 amount: sdk.ZeroInt(), 60 err: token.ErrInvalidAmount, 61 }, 62 } 63 64 for name, tc := range testCases { 65 t.Run(name, func(t *testing.T) { 66 msg := token.MsgSend{ 67 ContractId: tc.contractID, 68 From: tc.from.String(), 69 To: tc.to.String(), 70 Amount: tc.amount, 71 } 72 73 err := msg.ValidateBasic() 74 require.ErrorIs(t, err, tc.err) 75 if tc.err != nil { 76 return 77 } 78 79 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 80 }) 81 } 82 } 83 84 func TestMsgOperatorSend(t *testing.T) { 85 addrs := make([]sdk.AccAddress, 3) 86 for i := range addrs { 87 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 88 } 89 90 testCases := map[string]struct { 91 contractID string 92 operator sdk.AccAddress 93 from sdk.AccAddress 94 to sdk.AccAddress 95 amount sdk.Int 96 err error 97 }{ 98 "valid msg": { 99 contractID: "deadbeef", 100 operator: addrs[0], 101 from: addrs[1], 102 to: addrs[2], 103 amount: sdk.OneInt(), 104 }, 105 "invalid operator": { 106 contractID: "deadbeef", 107 from: addrs[1], 108 to: addrs[2], 109 amount: sdk.OneInt(), 110 err: sdkerrors.ErrInvalidAddress, 111 }, 112 "invalid contract id": { 113 operator: addrs[0], 114 from: addrs[1], 115 to: addrs[2], 116 amount: sdk.OneInt(), 117 err: class.ErrInvalidContractID, 118 }, 119 "invalid from": { 120 contractID: "deadbeef", 121 operator: addrs[0], 122 to: addrs[1], 123 amount: sdk.OneInt(), 124 err: sdkerrors.ErrInvalidAddress, 125 }, 126 "invalid to": { 127 contractID: "deadbeef", 128 operator: addrs[0], 129 from: addrs[1], 130 amount: sdk.OneInt(), 131 err: sdkerrors.ErrInvalidAddress, 132 }, 133 "invalid amount": { 134 contractID: "deadbeef", 135 operator: addrs[0], 136 from: addrs[1], 137 to: addrs[2], 138 amount: sdk.ZeroInt(), 139 err: token.ErrInvalidAmount, 140 }, 141 } 142 143 for name, tc := range testCases { 144 t.Run(name, func(t *testing.T) { 145 msg := token.MsgOperatorSend{ 146 ContractId: tc.contractID, 147 Operator: tc.operator.String(), 148 From: tc.from.String(), 149 To: tc.to.String(), 150 Amount: tc.amount, 151 } 152 153 err := msg.ValidateBasic() 154 require.ErrorIs(t, err, tc.err) 155 if tc.err != nil { 156 return 157 } 158 159 require.Equal(t, []sdk.AccAddress{tc.operator}, msg.GetSigners()) 160 }) 161 } 162 } 163 164 func TestMsgRevokeOperator(t *testing.T) { 165 addrs := make([]sdk.AccAddress, 2) 166 for i := range addrs { 167 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 168 } 169 170 testCases := map[string]struct { 171 contractID string 172 holder sdk.AccAddress 173 operator sdk.AccAddress 174 err error 175 }{ 176 "valid msg": { 177 contractID: "deadbeef", 178 holder: addrs[0], 179 operator: addrs[1], 180 }, 181 "invalid contract id": { 182 holder: addrs[0], 183 operator: addrs[1], 184 err: class.ErrInvalidContractID, 185 }, 186 "invalid holder": { 187 contractID: "deadbeef", 188 operator: addrs[1], 189 err: sdkerrors.ErrInvalidAddress, 190 }, 191 "invalid operator": { 192 contractID: "deadbeef", 193 holder: addrs[0], 194 err: sdkerrors.ErrInvalidAddress, 195 }, 196 "operator and holder should be different": { 197 contractID: "deadbeef", 198 holder: addrs[0], 199 operator: addrs[0], 200 err: token.ErrApproverProxySame, 201 }, 202 } 203 204 for name, tc := range testCases { 205 t.Run(name, func(t *testing.T) { 206 msg := token.MsgRevokeOperator{ 207 ContractId: tc.contractID, 208 Holder: tc.holder.String(), 209 Operator: tc.operator.String(), 210 } 211 212 err := msg.ValidateBasic() 213 require.ErrorIs(t, err, tc.err) 214 if tc.err != nil { 215 return 216 } 217 218 require.Equal(t, []sdk.AccAddress{tc.holder}, msg.GetSigners()) 219 }) 220 } 221 } 222 223 func TestMsgAuthorizeOperator(t *testing.T) { 224 addrs := make([]sdk.AccAddress, 2) 225 for i := range addrs { 226 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 227 } 228 229 testCases := map[string]struct { 230 contractID string 231 holder sdk.AccAddress 232 operator sdk.AccAddress 233 err error 234 }{ 235 "valid msg": { 236 contractID: "deadbeef", 237 holder: addrs[0], 238 operator: addrs[1], 239 }, 240 "invalid contract id": { 241 holder: addrs[0], 242 operator: addrs[1], 243 err: class.ErrInvalidContractID, 244 }, 245 "invalid holder": { 246 contractID: "deadbeef", 247 operator: addrs[1], 248 err: sdkerrors.ErrInvalidAddress, 249 }, 250 "empty operator": { 251 contractID: "deadbeef", 252 holder: addrs[0], 253 err: sdkerrors.ErrInvalidAddress, 254 }, 255 "proxy and approver should be different": { 256 contractID: "deadbeef", 257 holder: addrs[0], 258 operator: addrs[0], 259 err: token.ErrApproverProxySame, 260 }, 261 } 262 263 for name, tc := range testCases { 264 t.Run(name, func(t *testing.T) { 265 msg := token.MsgAuthorizeOperator{ 266 ContractId: tc.contractID, 267 Holder: tc.holder.String(), 268 Operator: tc.operator.String(), 269 } 270 271 err := msg.ValidateBasic() 272 require.ErrorIs(t, err, tc.err) 273 if tc.err != nil { 274 return 275 } 276 277 require.Equal(t, []sdk.AccAddress{tc.holder}, msg.GetSigners()) 278 }) 279 } 280 } 281 282 func TestMsgIssue(t *testing.T) { 283 addrs := make([]sdk.AccAddress, 2) 284 for i := range addrs { 285 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 286 } 287 288 testCases := map[string]struct { 289 owner sdk.AccAddress 290 to sdk.AccAddress 291 name string 292 symbol string 293 imageUri string 294 meta string 295 decimals int32 296 amount sdk.Int 297 err error 298 }{ 299 "valid msg": { 300 owner: addrs[0], 301 to: addrs[1], 302 name: "test", 303 symbol: "TT", 304 imageUri: "some URI", 305 meta: "some meta", 306 decimals: 8, 307 amount: sdk.OneInt(), 308 }, 309 "invalid owner": { 310 to: addrs[1], 311 name: "test", 312 symbol: "TT", 313 imageUri: "some URI", 314 meta: "some meta", 315 decimals: 8, 316 amount: sdk.OneInt(), 317 err: sdkerrors.ErrInvalidAddress, 318 }, 319 "invalid to": { 320 owner: addrs[0], 321 name: "test", 322 symbol: "TT", 323 imageUri: "some URI", 324 meta: "some meta", 325 decimals: 8, 326 amount: sdk.OneInt(), 327 err: sdkerrors.ErrInvalidAddress, 328 }, 329 "empty name": { 330 owner: addrs[0], 331 to: addrs[1], 332 symbol: "TT", 333 imageUri: "some URI", 334 meta: "some meta", 335 decimals: 8, 336 amount: sdk.OneInt(), 337 err: token.ErrInvalidTokenName, 338 }, 339 "long name": { 340 owner: addrs[0], 341 to: addrs[1], 342 name: "TOO Looooooooooooooog", 343 symbol: "TT", 344 imageUri: "some URI", 345 meta: "some meta", 346 decimals: 8, 347 amount: sdk.OneInt(), 348 err: token.ErrInvalidNameLength, 349 }, 350 "invalid symbol": { 351 owner: addrs[0], 352 to: addrs[1], 353 name: "test", 354 imageUri: "some URI", 355 meta: "some meta", 356 decimals: 8, 357 amount: sdk.OneInt(), 358 err: token.ErrInvalidTokenSymbol, 359 }, 360 "invalid symbol - start number": { 361 owner: addrs[0], 362 to: addrs[1], 363 name: "test", 364 symbol: "1TT", 365 imageUri: "some URI", 366 meta: "some meta", 367 decimals: 8, 368 amount: sdk.OneInt(), 369 err: token.ErrInvalidTokenSymbol, 370 }, 371 "invalid symbol - start lowercase letter": { 372 owner: addrs[0], 373 to: addrs[1], 374 name: "test", 375 symbol: "tTT", 376 imageUri: "some URI", 377 meta: "some meta", 378 decimals: 8, 379 amount: sdk.OneInt(), 380 err: token.ErrInvalidTokenSymbol, 381 }, 382 "invalid symbol - include lowercase letter": { 383 owner: addrs[0], 384 to: addrs[1], 385 name: "test", 386 symbol: "TtT", 387 imageUri: "some URI", 388 meta: "some meta", 389 decimals: 8, 390 amount: sdk.OneInt(), 391 err: token.ErrInvalidTokenSymbol, 392 }, 393 "invalid symbol - long length": { 394 owner: addrs[0], 395 to: addrs[1], 396 name: "test", 397 symbol: "TTTTT6", 398 imageUri: "some URI", 399 meta: "some meta", 400 decimals: 8, 401 amount: sdk.OneInt(), 402 err: token.ErrInvalidTokenSymbol, 403 }, 404 "invalid image uri": { 405 owner: addrs[0], 406 to: addrs[1], 407 name: "test", 408 symbol: "TT", 409 imageUri: string(make([]rune, 1001)), 410 meta: "some meta", 411 decimals: 8, 412 amount: sdk.OneInt(), 413 err: token.ErrInvalidImageURILength, 414 }, 415 "invalid meta": { 416 owner: addrs[0], 417 to: addrs[1], 418 name: "test", 419 symbol: "TT", 420 imageUri: "some URI", 421 meta: string(make([]rune, 1001)), 422 decimals: 8, 423 amount: sdk.OneInt(), 424 err: token.ErrInvalidMetaLength, 425 }, 426 "invalid decimals": { 427 owner: addrs[0], 428 to: addrs[1], 429 name: "test", 430 symbol: "TT", 431 imageUri: "some URI", 432 meta: "some meta", 433 decimals: 19, 434 amount: sdk.OneInt(), 435 err: token.ErrInvalidTokenDecimals, 436 }, 437 "invalid decimals - negative": { 438 owner: addrs[0], 439 to: addrs[1], 440 name: "test", 441 symbol: "TT", 442 imageUri: "some URI", 443 meta: "some meta", 444 decimals: -1, 445 amount: sdk.OneInt(), 446 err: token.ErrInvalidTokenDecimals, 447 }, 448 "invalid amount": { 449 owner: addrs[0], 450 to: addrs[1], 451 name: "test", 452 symbol: "TT", 453 imageUri: "some URI", 454 meta: "some meta", 455 decimals: 8, 456 amount: sdk.ZeroInt(), 457 err: token.ErrInvalidAmount, 458 }, 459 } 460 461 for name, tc := range testCases { 462 t.Run(name, func(t *testing.T) { 463 msg := token.MsgIssue{ 464 Owner: tc.owner.String(), 465 To: tc.to.String(), 466 Name: tc.name, 467 Symbol: tc.symbol, 468 Uri: tc.imageUri, 469 Meta: tc.meta, 470 Decimals: tc.decimals, 471 Amount: tc.amount, 472 } 473 474 err := msg.ValidateBasic() 475 require.ErrorIs(t, err, tc.err) 476 if tc.err != nil { 477 return 478 } 479 480 require.Equal(t, []sdk.AccAddress{tc.owner}, msg.GetSigners()) 481 }) 482 } 483 } 484 485 func TestMsgMint(t *testing.T) { 486 addrs := make([]sdk.AccAddress, 2) 487 for i := range addrs { 488 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 489 } 490 491 testCases := map[string]struct { 492 contractID string 493 grantee sdk.AccAddress 494 to sdk.AccAddress 495 amount sdk.Int 496 err error 497 }{ 498 "valid msg": { 499 contractID: "deadbeef", 500 grantee: addrs[0], 501 to: addrs[1], 502 amount: sdk.OneInt(), 503 }, 504 "invalid contract id": { 505 grantee: addrs[0], 506 to: addrs[1], 507 amount: sdk.OneInt(), 508 err: class.ErrInvalidContractID, 509 }, 510 "invalid grantee": { 511 contractID: "deadbeef", 512 to: addrs[1], 513 amount: sdk.OneInt(), 514 err: sdkerrors.ErrInvalidAddress, 515 }, 516 "invalid to": { 517 contractID: "deadbeef", 518 grantee: addrs[0], 519 amount: sdk.OneInt(), 520 err: sdkerrors.ErrInvalidAddress, 521 }, 522 "zero amount": { 523 contractID: "deadbeef", 524 grantee: addrs[0], 525 to: addrs[1], 526 amount: sdk.ZeroInt(), 527 err: token.ErrInvalidAmount, 528 }, 529 "negative amount": { 530 contractID: "deadbeef", 531 grantee: addrs[0], 532 to: addrs[1], 533 amount: sdk.NewInt(-10), 534 err: token.ErrInvalidAmount, 535 }, 536 } 537 538 for name, tc := range testCases { 539 t.Run(name, func(t *testing.T) { 540 msg := token.MsgMint{ 541 ContractId: tc.contractID, 542 From: tc.grantee.String(), 543 To: tc.to.String(), 544 Amount: tc.amount, 545 } 546 547 err := msg.ValidateBasic() 548 require.ErrorIs(t, err, tc.err) 549 if tc.err != nil { 550 return 551 } 552 553 require.Equal(t, []sdk.AccAddress{tc.grantee}, msg.GetSigners()) 554 }) 555 } 556 } 557 558 func TestMsgBurn(t *testing.T) { 559 addrs := make([]sdk.AccAddress, 1) 560 for i := range addrs { 561 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 562 } 563 564 testCases := map[string]struct { 565 contractID string 566 from sdk.AccAddress 567 amount sdk.Int 568 err error 569 }{ 570 "valid msg": { 571 contractID: "deadbeef", 572 from: addrs[0], 573 amount: sdk.OneInt(), 574 }, 575 "invalid contract id": { 576 from: addrs[0], 577 amount: sdk.OneInt(), 578 err: class.ErrInvalidContractID, 579 }, 580 "invalid from": { 581 contractID: "deadbeef", 582 amount: sdk.OneInt(), 583 err: sdkerrors.ErrInvalidAddress, 584 }, 585 "invalid amount": { 586 contractID: "deadbeef", 587 from: addrs[0], 588 amount: sdk.ZeroInt(), 589 err: token.ErrInvalidAmount, 590 }, 591 "negative amount": { 592 contractID: "deadbeef", 593 from: addrs[0], 594 amount: sdk.NewInt(-10), 595 err: token.ErrInvalidAmount, 596 }, 597 } 598 599 for name, tc := range testCases { 600 t.Run(name, func(t *testing.T) { 601 msg := token.MsgBurn{ 602 ContractId: tc.contractID, 603 From: tc.from.String(), 604 Amount: tc.amount, 605 } 606 607 err := msg.ValidateBasic() 608 require.ErrorIs(t, err, tc.err) 609 if tc.err != nil { 610 return 611 } 612 613 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 614 }) 615 } 616 } 617 618 func TestMsgOperatorBurn(t *testing.T) { 619 addrs := make([]sdk.AccAddress, 2) 620 for i := range addrs { 621 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 622 } 623 624 testCases := map[string]struct { 625 contractID string 626 grantee sdk.AccAddress 627 from sdk.AccAddress 628 amount sdk.Int 629 err error 630 }{ 631 "valid msg": { 632 contractID: "deadbeef", 633 grantee: addrs[0], 634 from: addrs[1], 635 amount: sdk.OneInt(), 636 }, 637 "invalid contract id": { 638 grantee: addrs[0], 639 from: addrs[1], 640 amount: sdk.OneInt(), 641 err: class.ErrInvalidContractID, 642 }, 643 "invalid grantee": { 644 contractID: "deadbeef", 645 from: addrs[1], 646 amount: sdk.OneInt(), 647 err: sdkerrors.ErrInvalidAddress, 648 }, 649 "invalid from": { 650 contractID: "deadbeef", 651 grantee: addrs[0], 652 amount: sdk.OneInt(), 653 err: sdkerrors.ErrInvalidAddress, 654 }, 655 "invalid amount": { 656 contractID: "deadbeef", 657 grantee: addrs[0], 658 from: addrs[1], 659 amount: sdk.ZeroInt(), 660 err: token.ErrInvalidAmount, 661 }, 662 } 663 664 for name, tc := range testCases { 665 t.Run(name, func(t *testing.T) { 666 msg := token.MsgOperatorBurn{ 667 ContractId: tc.contractID, 668 Operator: tc.grantee.String(), 669 From: tc.from.String(), 670 Amount: tc.amount, 671 } 672 673 err := msg.ValidateBasic() 674 require.ErrorIs(t, err, tc.err) 675 if tc.err != nil { 676 return 677 } 678 679 require.Equal(t, []sdk.AccAddress{tc.grantee}, msg.GetSigners()) 680 }) 681 } 682 } 683 684 func TestMsgModify(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 validChange := token.Attribute{Key: token.AttributeKeyName.String(), Value: "New test"} 691 testCases := map[string]struct { 692 contractID string 693 grantee sdk.AccAddress 694 changes []token.Attribute 695 err error 696 }{ 697 "valid msg": { 698 contractID: "deadbeef", 699 grantee: addrs[0], 700 changes: []token.Attribute{validChange}, 701 }, 702 "invalid contract id": { 703 grantee: addrs[0], 704 changes: []token.Attribute{validChange}, 705 err: class.ErrInvalidContractID, 706 }, 707 "invalid grantee": { 708 contractID: "deadbeef", 709 changes: []token.Attribute{validChange}, 710 err: sdkerrors.ErrInvalidAddress, 711 }, 712 "invalid key of change": { 713 contractID: "deadbeef", 714 grantee: addrs[0], 715 changes: []token.Attribute{{Key: strings.ToUpper(token.AttributeKeyName.String()), Value: "tt"}}, 716 err: token.ErrInvalidChangesField, 717 }, 718 "invalid value of change": { 719 contractID: "deadbeef", 720 grantee: addrs[0], 721 changes: []token.Attribute{{Key: token.AttributeKeyName.String(), Value: string(make([]rune, 21))}}, 722 err: token.ErrInvalidNameLength, 723 }, 724 "empty changes": { 725 contractID: "deadbeef", 726 grantee: addrs[0], 727 err: token.ErrEmptyChanges, 728 }, 729 "duplicated changes": { 730 contractID: "deadbeef", 731 grantee: addrs[0], 732 changes: []token.Attribute{ 733 {Key: token.AttributeKeyImageURI.String(), Value: "hello"}, 734 {Key: token.AttributeKeyURI.String(), Value: "world"}, 735 }, 736 err: token.ErrDuplicateChangesField, 737 }, 738 "over max length changes(uri)": { 739 contractID: "deadbeef", 740 grantee: addrs[0], 741 changes: []token.Attribute{{Key: token.AttributeKeyURI.String(), Value: string(make([]rune, 1001))}}, 742 err: token.ErrInvalidImageURILength, 743 }, 744 "over max length changes(meta)": { 745 contractID: "deadbeef", 746 grantee: addrs[0], 747 changes: []token.Attribute{{Key: token.AttributeKeyMeta.String(), Value: string(make([]rune, 1001))}}, 748 err: token.ErrInvalidMetaLength, 749 }, 750 } 751 752 for name, tc := range testCases { 753 t.Run(name, func(t *testing.T) { 754 msg := token.MsgModify{ 755 ContractId: tc.contractID, 756 Owner: tc.grantee.String(), 757 Changes: tc.changes, 758 } 759 760 err := msg.ValidateBasic() 761 require.ErrorIs(t, err, tc.err) 762 if tc.err != nil { 763 return 764 } 765 766 require.Equal(t, []sdk.AccAddress{tc.grantee}, msg.GetSigners()) 767 }) 768 } 769 } 770 771 func TestMsgGrantPermission(t *testing.T) { 772 addrs := make([]sdk.AccAddress, 2) 773 for i := range addrs { 774 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 775 } 776 777 testCases := map[string]struct { 778 contractID string 779 from sdk.AccAddress 780 to sdk.AccAddress 781 permission string 782 err error 783 }{ 784 "valid msg": { 785 contractID: "deadbeef", 786 from: addrs[0], 787 to: addrs[1], 788 permission: token.LegacyPermissionMint.String(), 789 }, 790 "invalid contract id": { 791 from: addrs[0], 792 to: addrs[1], 793 permission: token.LegacyPermissionMint.String(), 794 err: class.ErrInvalidContractID, 795 }, 796 "invalid from": { 797 contractID: "deadbeef", 798 to: addrs[1], 799 permission: token.LegacyPermissionMint.String(), 800 err: sdkerrors.ErrInvalidAddress, 801 }, 802 "invalid to": { 803 contractID: "deadbeef", 804 from: addrs[0], 805 permission: token.LegacyPermissionMint.String(), 806 err: sdkerrors.ErrInvalidAddress, 807 }, 808 "invalid permission": { 809 contractID: "deadbeef", 810 from: addrs[0], 811 to: addrs[1], 812 err: sdkerrors.ErrInvalidPermission, 813 }, 814 } 815 816 for name, tc := range testCases { 817 t.Run(name, func(t *testing.T) { 818 msg := token.MsgGrantPermission{ 819 ContractId: tc.contractID, 820 From: tc.from.String(), 821 To: tc.to.String(), 822 Permission: tc.permission, 823 } 824 825 err := msg.ValidateBasic() 826 require.ErrorIs(t, err, tc.err) 827 if tc.err != nil { 828 return 829 } 830 831 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 832 }) 833 } 834 } 835 836 func TestMsgRevokePermission(t *testing.T) { 837 addrs := make([]sdk.AccAddress, 1) 838 for i := range addrs { 839 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 840 } 841 842 testCases := map[string]struct { 843 contractID string 844 from sdk.AccAddress 845 permission string 846 err error 847 }{ 848 "valid msg": { 849 contractID: "deadbeef", 850 from: addrs[0], 851 permission: token.LegacyPermissionMint.String(), 852 }, 853 "invalid contract id": { 854 from: addrs[0], 855 permission: token.LegacyPermissionMint.String(), 856 err: class.ErrInvalidContractID, 857 }, 858 "invalid from": { 859 contractID: "deadbeef", 860 permission: token.LegacyPermissionMint.String(), 861 err: sdkerrors.ErrInvalidAddress, 862 }, 863 "invalid permission": { 864 contractID: "deadbeef", 865 from: addrs[0], 866 err: sdkerrors.ErrInvalidPermission, 867 }, 868 } 869 870 for name, tc := range testCases { 871 t.Run(name, func(t *testing.T) { 872 msg := token.MsgRevokePermission{ 873 ContractId: tc.contractID, 874 From: tc.from.String(), 875 Permission: tc.permission, 876 } 877 878 err := msg.ValidateBasic() 879 require.ErrorIs(t, err, tc.err) 880 if tc.err != nil { 881 return 882 } 883 884 require.Equal(t, []sdk.AccAddress{tc.from}, msg.GetSigners()) 885 }) 886 } 887 } 888 889 func TestAminoJSON(t *testing.T) { 890 tx := legacytx.StdTx{} 891 contractId := "deadbeef" 892 893 addrs := make([]sdk.AccAddress, 3) 894 for i := range addrs { 895 addrs[i] = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) 896 } 897 898 testCases := map[string]struct { 899 msg legacytx.LegacyMsg 900 expectedType string 901 expected string 902 }{ 903 "MsgSend": { 904 &token.MsgSend{ 905 ContractId: contractId, 906 From: addrs[0].String(), 907 To: addrs[1].String(), 908 Amount: sdk.OneInt(), 909 }, 910 "/lbm.token.v1.MsgSend", 911 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgSend\",\"value\":{\"amount\":\"1\",\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 912 }, 913 "MsgOperatorSend": { 914 &token.MsgOperatorSend{ 915 ContractId: contractId, 916 Operator: addrs[0].String(), 917 From: addrs[1].String(), 918 To: addrs[2].String(), 919 Amount: sdk.OneInt(), 920 }, 921 "/lbm.token.v1.MsgOperatorSend", 922 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorSend\",\"value\":{\"amount\":\"1\",\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String(), addrs[2].String()), 923 }, 924 "MsgRevokeOperator": { 925 &token.MsgRevokeOperator{ 926 ContractId: contractId, 927 Holder: addrs[0].String(), 928 Operator: addrs[1].String(), 929 }, 930 "/lbm.token.v1.MsgRevokeOperator", 931 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/token/MsgRevokeOperator\",\"value\":{\"contract_id\":\"deadbeef\",\"holder\":\"%s\",\"operator\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 932 }, 933 "MsgAuthorizeOperator": { 934 &token.MsgAuthorizeOperator{ 935 ContractId: contractId, 936 Holder: addrs[0].String(), 937 Operator: addrs[1].String(), 938 }, 939 "/lbm.token.v1.MsgAuthorizeOperator", 940 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/token/MsgAuthorizeOperator\",\"value\":{\"contract_id\":\"deadbeef\",\"holder\":\"%s\",\"operator\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 941 }, 942 "MsgIssue": { 943 &token.MsgIssue{ 944 Name: "Test Name", 945 Symbol: "LN", 946 Uri: "http://image.url", 947 Meta: "This is test", 948 Decimals: 6, 949 Mintable: false, 950 Owner: addrs[0].String(), 951 To: addrs[1].String(), 952 Amount: sdk.NewInt(1000000), 953 }, 954 "/lbm.token.v1.MsgIssue", 955 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgIssue\",\"value\":{\"amount\":\"1000000\",\"decimals\":6,\"meta\":\"This is test\",\"name\":\"Test Name\",\"owner\":\"%s\",\"symbol\":\"LN\",\"to\":\"%s\",\"uri\":\"http://image.url\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 956 }, 957 "MsgGrantPermission": { 958 &token.MsgGrantPermission{ 959 ContractId: contractId, 960 From: addrs[0].String(), 961 To: addrs[1].String(), 962 Permission: token.LegacyPermissionMint.String(), 963 }, 964 "/lbm.token.v1.MsgGrantPermission", 965 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/token/MsgGrantPermission\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"permission\":\"mint\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 966 }, 967 "MsgRevokePermission": { 968 &token.MsgRevokePermission{ 969 ContractId: contractId, 970 From: addrs[0].String(), 971 Permission: token.LegacyPermissionMint.String(), 972 }, 973 "/lbm.token.v1.MsgRevokePermission", 974 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/token/MsgRevokePermission\",\"value\":{\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"permission\":\"mint\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 975 }, 976 "MsgMint": { 977 &token.MsgMint{ 978 ContractId: contractId, 979 From: addrs[0].String(), 980 To: addrs[1].String(), 981 Amount: sdk.NewInt(1000000), 982 }, 983 "/lbm.token.v1.MsgMint", 984 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgMint\",\"value\":{\"amount\":\"1000000\",\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"to\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String(), addrs[1].String()), 985 }, 986 "MsgBurn": { 987 &token.MsgBurn{ 988 ContractId: contractId, 989 From: addrs[0].String(), 990 Amount: sdk.Int{}, 991 }, 992 "/lbm.token.v1.MsgBurn", 993 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgBurn\",\"value\":{\"amount\":\"0\",\"contract_id\":\"deadbeef\",\"from\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 994 }, 995 "MsgOperatorBurn": { 996 &token.MsgOperatorBurn{ 997 ContractId: contractId, 998 Operator: addrs[0].String(), 999 From: addrs[1].String(), 1000 Amount: sdk.NewInt(1000000), 1001 }, 1002 "/lbm.token.v1.MsgOperatorBurn", 1003 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/MsgOperatorBurn\",\"value\":{\"amount\":\"1000000\",\"contract_id\":\"deadbeef\",\"from\":\"%s\",\"operator\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[1].String(), addrs[0].String()), 1004 }, 1005 "MsgModify": { 1006 &token.MsgModify{ 1007 ContractId: contractId, 1008 Owner: addrs[0].String(), 1009 Changes: []token.Attribute{{Key: token.AttributeKeyName.String(), Value: "New test"}}, 1010 }, 1011 "/lbm.token.v1.MsgModify", 1012 fmt.Sprintf("{\"account_number\":\"1\",\"chain_id\":\"foo\",\"fee\":{\"amount\":[],\"gas\":\"0\"},\"memo\":\"memo\",\"msgs\":[{\"type\":\"lbm-sdk/token/MsgModify\",\"value\":{\"changes\":[{\"key\":\"name\",\"value\":\"New test\"}],\"contract_id\":\"deadbeef\",\"owner\":\"%s\"}}],\"sequence\":\"1\",\"timeout_height\":\"1\"}", addrs[0].String()), 1013 }, 1014 } 1015 1016 for name, tc := range testCases { 1017 t.Run(name, func(t *testing.T) { 1018 tx.Msgs = []sdk.Msg{tc.msg} 1019 require.Equal(t, token.RouterKey, tc.msg.Route()) 1020 require.Equal(t, tc.expectedType, tc.msg.Type()) 1021 require.Equal(t, tc.expected, string(legacytx.StdSignBytes("foo", 1, 1, 1, legacytx.StdFee{}, []sdk.Msg{tc.msg}, "memo"))) 1022 }) 1023 } 1024 }