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