github.com/InjectiveLabs/sdk-go@v1.53.0/chain/permissions/types/types.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 6 "cosmossdk.io/errors" 7 sdk "github.com/cosmos/cosmos-sdk/types" 8 9 tftypes "github.com/InjectiveLabs/sdk-go/chain/tokenfactory/types" 10 ) 11 12 const ( 13 EVERYONE = "EVERYONE" 14 MaxPerm = uint32(Action_MINT) | uint32(Action_RECEIVE) | uint32(Action_BURN) 15 ) 16 17 type WasmHookMsg struct { 18 From sdk.AccAddress `json:"from_address"` 19 To sdk.AccAddress `json:"to_address"` 20 Action string `json:"action"` 21 Amounts sdk.Coins `json:"amounts"` 22 } 23 24 func NewWasmHookMsg(fromAddr, toAddr sdk.AccAddress, action Action, amount sdk.Coin) WasmHookMsg { 25 return WasmHookMsg{ 26 From: fromAddr, 27 To: toAddr, 28 Action: action.String(), 29 Amounts: sdk.NewCoins(amount), 30 } 31 } 32 33 func GetWasmHookMsgBytes(fromAddr, toAddr sdk.AccAddress, action Action, amount sdk.Coin) ([]byte, error) { 34 wasmHookMsg := struct { 35 SendRestriction WasmHookMsg `json:"send_restriction"` 36 }{NewWasmHookMsg(fromAddr, toAddr, action, amount)} 37 38 bz, err := json.Marshal(wasmHookMsg) 39 if err != nil { 40 return nil, err 41 } 42 43 return bz, nil 44 } 45 46 func (n *Namespace) Validate() error { 47 if err := n.ValidateBasicParams(); err != nil { 48 return err 49 } 50 51 if err := n.ValidateEveryoneRole(); err != nil { 52 return err 53 } 54 55 if err := n.ValidateRoles(false); err != nil { 56 return err 57 } 58 59 return nil 60 } 61 62 func (n *Namespace) ValidateBasicParams() error { 63 if _, _, err := tftypes.DeconstructDenom(n.Denom); err != nil { 64 return errors.Wrap(err, "permissions namespace can only be applied to tokenfactory denoms") 65 } 66 67 // existing wasm hook contract 68 if n.WasmHook != "" { 69 if _, err := sdk.AccAddressFromBech32(n.WasmHook); err != nil { 70 return ErrInvalidWasmHook 71 } 72 } 73 74 return nil 75 } 76 77 func (n *Namespace) ValidateRoles(isForUpdate bool) error { 78 // role_permissions 79 foundRoles := make(map[string]struct{}, len(n.RolePermissions)) 80 for _, rolePerm := range n.RolePermissions { 81 if _, ok := foundRoles[rolePerm.Role]; ok { 82 return errors.Wrapf(ErrInvalidPermission, "permissions for the role %s set multiple times?", rolePerm.Role) 83 } 84 if rolePerm.Permissions > MaxPerm { 85 return errors.Wrapf(ErrInvalidPermission, "permissions %d for the role %s is bigger than maximum expected %d", rolePerm.Permissions, rolePerm.Role, MaxPerm) 86 } 87 foundRoles[rolePerm.Role] = struct{}{} 88 } 89 90 // address_roles 91 foundAddresses := make(map[string]struct{}, len(n.AddressRoles)) 92 for _, addrRoles := range n.AddressRoles { 93 if _, err := sdk.AccAddressFromBech32(addrRoles.Address); err != nil { 94 return errors.Wrapf(err, "invalid address %s", addrRoles.Address) 95 } 96 if _, ok := foundAddresses[addrRoles.Address]; ok { 97 return errors.Wrapf(ErrInvalidRole, "address %s is assigned new roles multiple times?", addrRoles.Address) 98 } 99 for _, role := range addrRoles.Roles { 100 _, found := foundRoles[role] 101 if !isForUpdate && !found { 102 return errors.Wrapf(ErrUnknownRole, "role %s has no defined permissions", role) 103 } 104 if role == EVERYONE { 105 return errors.Wrapf(ErrInvalidRole, "role %s should not be explicitly attached to address, you need to remove address from the list completely instead", EVERYONE) 106 } 107 } 108 foundAddresses[addrRoles.Address] = struct{}{} 109 } 110 111 return nil 112 } 113 114 func (n *Namespace) ValidateEveryoneRole() error { 115 // role_permissions 116 for _, rolePerm := range n.RolePermissions { 117 if rolePerm.Role == EVERYONE { 118 return nil 119 } 120 } 121 122 return errors.Wrapf(ErrInvalidPermission, "permissions for role %s should be explicitly set", EVERYONE) 123 } 124 125 func (n *Namespace) CheckActionValidity(action Action) error { 126 // check that action is not paused 127 switch action { 128 case Action_MINT: 129 if n.MintsPaused { 130 return errors.Wrap(ErrRestrictedAction, "mints paused") 131 } 132 case Action_RECEIVE: 133 if n.SendsPaused { 134 return errors.Wrap(ErrRestrictedAction, "sends paused") 135 } 136 case Action_BURN: 137 if n.BurnsPaused { 138 return errors.Wrap(ErrRestrictedAction, "burns paused") 139 } 140 } 141 return nil 142 } 143 144 func (a Action) DeriveActor(fromAddr, toAddr sdk.AccAddress) sdk.AccAddress { 145 switch a { 146 case Action_MINT, Action_RECEIVE: 147 return toAddr 148 case Action_BURN: 149 return fromAddr 150 } 151 return fromAddr 152 } 153 154 func NewEmptyVoucher(denom string) sdk.Coin { 155 return sdk.NewInt64Coin(denom, 0) 156 }