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  }