Skip to content

Commit

Permalink
add handler
Browse files Browse the repository at this point in the history
  • Loading branch information
DuyVK23 committed Jun 30, 2024
1 parent 53d4645 commit 0020596
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 66 deletions.
28 changes: 14 additions & 14 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
version: 1
validation: sovereign
accounts:
- name: alice
coins:
- 20000token
- 200000000stake
- name: bob
coins:
- 10000token
- 100000000stake
accounts:
- name: alice
coins:
- 20000token
- 10000foocoin
- 200000000stake
- name: bob
coins:
- 10000token
- 100000000stake
client:
openapi:
path: docs/static/openapi.yml
faucet:
name: bob
coins:
- 5token
- 100000stake
- 5token
- 100000stake
validators:
- name: alice
bonded: 100000000stake
- name: alice
bonded: 100000000stake
30 changes: 24 additions & 6 deletions x/loan/keeper/msg_server_approve_loan.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,34 @@ package keeper
import (
"context"

"loan/x/loan/types"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"loan/x/loan/types"
)

func (k msgServer) ApproveLoan(goCtx context.Context, msg *types.MsgApproveLoan) (*types.MsgApproveLoanResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// TODO: Handling the message
_ = ctx

loan, found := k.GetLoan(ctx, msg.Id)
if !found {
return nil, errorsmod.Wrapf(sdkerrors.ErrKeyNotFound, "key %d doesn't exist", msg.Id)
}
if loan.State != "requested" {
return nil, errorsmod.Wrapf(types.ErrWrongLoanState, "%v", loan.State)
}
lender, _ := sdk.AccAddressFromBech32(msg.Creator)
borrower, _ := sdk.AccAddressFromBech32(loan.Borrower)
amount, err := sdk.ParseCoinsNormalized(loan.Amount)
if err != nil {
return nil, errorsmod.Wrap(types.ErrWrongLoanState, "Cannot parse coins in loan amount")
}
err = k.bankKeeper.SendCoins(ctx, lender, borrower, amount)
if err != nil {
return nil, err
}
loan.Lender = msg.Creator
loan.State = "approved"
k.SetLoan(ctx, loan)
return &types.MsgApproveLoanResponse{}, nil
}
28 changes: 22 additions & 6 deletions x/loan/keeper/msg_server_cancel_loan.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,32 @@ package keeper
import (
"context"

"loan/x/loan/types"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"loan/x/loan/types"
)

func (k msgServer) CancelLoan(goCtx context.Context, msg *types.MsgCancelLoan) (*types.MsgCancelLoanResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// TODO: Handling the message
_ = ctx

loan, found := k.GetLoan(ctx, msg.Id)
if !found {
return nil, errorsmod.Wrapf(sdkerrors.ErrKeyNotFound, "key %d doesn't exist", msg.Id)
}
if loan.Borrower != msg.Creator {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Cannot cancel: not the borrower")
}
if loan.State != "requested" {
return nil, errorsmod.Wrapf(types.ErrWrongLoanState, "%v", loan.State)
}
borrower, _ := sdk.AccAddressFromBech32(loan.Borrower)
collateral, _ := sdk.ParseCoinsNormalized(loan.Collateral)
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, borrower, collateral)
if err != nil {
return nil, err
}
loan.State = "cancelled"
k.SetLoan(ctx, loan)
return &types.MsgCancelLoanResponse{}, nil
}
36 changes: 30 additions & 6 deletions x/loan/keeper/msg_server_liquidate_loan.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,41 @@ package keeper

import (
"context"
"strconv"

"loan/x/loan/types"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"loan/x/loan/types"
)

func (k msgServer) LiquidateLoan(goCtx context.Context, msg *types.MsgLiquidateLoan) (*types.MsgLiquidateLoanResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// TODO: Handling the message
_ = ctx

loan, found := k.GetLoan(ctx, msg.Id)
if !found {
return nil, errorsmod.Wrapf(sdkerrors.ErrKeyNotFound, "key %d doesn't exist", msg.Id)
}
if loan.Lender != msg.Creator {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Cannot liquidate: not the lender")
}
if loan.State != "approved" {
return nil, errorsmod.Wrapf(types.ErrWrongLoanState, "%v", loan.State)
}
lender, _ := sdk.AccAddressFromBech32(loan.Lender)
collateral, _ := sdk.ParseCoinsNormalized(loan.Collateral)
deadline, err := strconv.ParseInt(loan.Deadline, 10, 64)
if err != nil {
panic(err)
}
if ctx.BlockHeight() < deadline {
return nil, errorsmod.Wrap(types.ErrDeadline, "Cannot liquidate before deadline")
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, lender, collateral)
if err != nil {
return nil, err
}
loan.State = "liquidated"
k.SetLoan(ctx, loan)
return &types.MsgLiquidateLoanResponse{}, nil
}
39 changes: 33 additions & 6 deletions x/loan/keeper/msg_server_repay_loan.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,43 @@ package keeper
import (
"context"

"loan/x/loan/types"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"loan/x/loan/types"
)

func (k msgServer) RepayLoan(goCtx context.Context, msg *types.MsgRepayLoan) (*types.MsgRepayLoanResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// TODO: Handling the message
_ = ctx

loan, found := k.GetLoan(ctx, msg.Id)
if !found {
return nil, errorsmod.Wrapf(sdkerrors.ErrKeyNotFound, "key %d doesn't exist", msg.Id)
}
if loan.State != "approved" {
return nil, errorsmod.Wrapf(types.ErrWrongLoanState, "%v", loan.State)
}
lender, _ := sdk.AccAddressFromBech32(loan.Lender)
borrower, _ := sdk.AccAddressFromBech32(loan.Borrower)
if msg.Creator != loan.Borrower {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Cannot repay: not the borrower")
}
amount, _ := sdk.ParseCoinsNormalized(loan.Amount)
fee, _ := sdk.ParseCoinsNormalized(loan.Fee)
collateral, _ := sdk.ParseCoinsNormalized(loan.Collateral)
err := k.bankKeeper.SendCoins(ctx, borrower, lender, amount)
if err != nil {
return nil, err
}
err = k.bankKeeper.SendCoins(ctx, borrower, lender, fee)
if err != nil {
return nil, err
}
err = k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, borrower, collateral)
if err != nil {
return nil, err
}
loan.State = "repayed"
k.SetLoan(ctx, loan)
return &types.MsgRepayLoanResponse{}, nil
}
29 changes: 23 additions & 6 deletions x/loan/keeper/msg_server_request_loan.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,33 @@ package keeper
import (
"context"

"loan/x/loan/types"

sdk "github.com/cosmos/cosmos-sdk/types"

"loan/x/loan/types"
)

func (k msgServer) RequestLoan(goCtx context.Context, msg *types.MsgRequestLoan) (*types.MsgRequestLoanResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// TODO: Handling the message
_ = ctx

var loan = types.Loan{
Amount: msg.Amount,
Fee: msg.Fee,
Collateral: msg.Collateral,
Deadline: msg.Deadline,
State: "requested",
Borrower: msg.Creator,
}
borrower, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
panic(err)
}
collateral, err := sdk.ParseCoinsNormalized(loan.Collateral)
if err != nil {
panic(err)
}
sdkError := k.bankKeeper.SendCoinsFromAccountToModule(ctx, borrower, types.ModuleName, collateral)
if sdkError != nil {
return nil, sdkError
}
k.AppendLoan(ctx, loan)
return &types.MsgRequestLoanResponse{}, nil
}
7 changes: 2 additions & 5 deletions x/loan/types/errors.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package types

// DONTCOVER

import (
sdkerrors "cosmossdk.io/errors"
)

// x/loan module sentinel errors
var (
ErrInvalidSigner = sdkerrors.Register(ModuleName, 1100, "expected gov account as only signer for proposal message")
ErrSample = sdkerrors.Register(ModuleName, 1101, "sample error")
ErrWrongLoanState = sdkerrors.Register(ModuleName, 2, "wrong loan state")
ErrDeadline = sdkerrors.Register(ModuleName, 3, "deadline")
)
6 changes: 4 additions & 2 deletions x/loan/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ type AccountKeeper interface {

// BankKeeper defines the expected interface for the Bank module.
type BankKeeper interface {
SpendableCoins(context.Context, sdk.AccAddress) sdk.Coins
// Methods imported from bank should be defined here
// SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
SendCoins(ctx context.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
}

// ParamSubspace defines the expected Subspace interface for parameters.
Expand Down
43 changes: 28 additions & 15 deletions x/loan/types/message_request_loan.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,40 @@
package types

import (
"strconv"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

var _ sdk.Msg = &MsgRequestLoan{}

func NewMsgRequestLoan(creator string, amount string, fee string, collateral string, deadline string) *MsgRequestLoan {
return &MsgRequestLoan{
Creator: creator,
Amount: amount,
Fee: fee,
Collateral: collateral,
Deadline: deadline,
}
}

func (msg *MsgRequestLoan) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
return errorsmod.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err)
}
amount, _ := sdk.ParseCoinsNormalized(msg.Amount)
if !amount.IsValid() {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "amount is not a valid Coins object")
}
if amount.Empty() {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "amount is empty")
}
fee, _ := sdk.ParseCoinsNormalized(msg.Fee)
if !fee.IsValid() {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "fee is not a valid Coins object")
}
deadline, err := strconv.ParseInt(msg.Deadline, 10, 64)
if err != nil {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "deadline is not an integer")
}
if deadline <= 0 {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "deadline should be a positive integer")
}
collateral, _ := sdk.ParseCoinsNormalized(msg.Collateral)
if !collateral.IsValid() {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "collateral is not a valid Coins object")
}
if collateral.Empty() {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "collateral is empty")
}
return nil
}
}

0 comments on commit 0020596

Please sign in to comment.