github.com/Finschia/finschia-sdk@v0.49.1/x/auth/vesting/msg_server.go (about) 1 package vesting 2 3 import ( 4 "context" 5 6 "github.com/hashicorp/go-metrics" 7 8 "github.com/Finschia/finschia-sdk/telemetry" 9 sdk "github.com/Finschia/finschia-sdk/types" 10 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 11 "github.com/Finschia/finschia-sdk/x/auth/keeper" 12 authtypes "github.com/Finschia/finschia-sdk/x/auth/types" 13 "github.com/Finschia/finschia-sdk/x/auth/vesting/types" 14 ) 15 16 type msgServer struct { 17 keeper.AccountKeeper 18 types.BankKeeper 19 } 20 21 // NewMsgServerImpl returns an implementation of the vesting MsgServer interface, 22 // wrapping the corresponding AccountKeeper and BankKeeper. 23 func NewMsgServerImpl(k keeper.AccountKeeper, bk types.BankKeeper) types.MsgServer { 24 return &msgServer{AccountKeeper: k, BankKeeper: bk} 25 } 26 27 var _ types.MsgServer = msgServer{} 28 29 func (s msgServer) CreateVestingAccount(goCtx context.Context, msg *types.MsgCreateVestingAccount) (*types.MsgCreateVestingAccountResponse, error) { 30 ctx := sdk.UnwrapSDKContext(goCtx) 31 ak := s.AccountKeeper 32 bk := s.BankKeeper 33 34 if err := bk.IsSendEnabledCoins(ctx, msg.Amount...); err != nil { 35 return nil, err 36 } 37 38 from, err := sdk.AccAddressFromBech32(msg.FromAddress) 39 if err != nil { 40 return nil, err 41 } 42 to, err := sdk.AccAddressFromBech32(msg.ToAddress) 43 if err != nil { 44 return nil, err 45 } 46 47 if bk.BlockedAddr(to) { 48 return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive funds", msg.ToAddress) 49 } 50 51 if acc := ak.GetAccount(ctx, to); acc != nil { 52 return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "account %s already exists", msg.ToAddress) 53 } 54 55 baseAccount := ak.NewAccountWithAddress(ctx, to) 56 if _, ok := baseAccount.(*authtypes.BaseAccount); !ok { 57 return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid account type; expected: BaseAccount, got: %T", baseAccount) 58 } 59 60 baseVestingAccount := types.NewBaseVestingAccount(baseAccount.(*authtypes.BaseAccount), msg.Amount.Sort(), msg.EndTime) 61 62 var acc authtypes.AccountI 63 64 if msg.Delayed { 65 acc = types.NewDelayedVestingAccountRaw(baseVestingAccount) 66 } else { 67 acc = types.NewContinuousVestingAccountRaw(baseVestingAccount, ctx.BlockTime().Unix()) 68 } 69 70 ak.SetAccount(ctx, acc) 71 72 defer func() { 73 telemetry.IncrCounter(1, "new", "account") 74 75 for _, a := range msg.Amount { 76 if a.Amount.IsInt64() { 77 telemetry.SetGaugeWithLabels( 78 []string{"tx", "msg", "create_vesting_account"}, 79 float32(a.Amount.Int64()), 80 []metrics.Label{telemetry.NewLabel("denom", a.Denom)}, 81 ) 82 } 83 } 84 }() 85 86 err = bk.SendCoins(ctx, from, to, msg.Amount) 87 if err != nil { 88 return nil, err 89 } 90 91 return &types.MsgCreateVestingAccountResponse{}, nil 92 }