Approve a loan
After a loan request has been made, it is possible for another account to approve the loan and accept the terms proposed by the borrower. This process involves the transfer of the requested funds from the lender to the borrower.
To be eligible for approval, a loan must have a status of "requested." This means that the borrower has made a request for a loan and is waiting for a lender to agree to the terms and provide the funds. Once a lender has decided to approve the loan, they can initiate the transfer of the funds to the borrower.
Upon loan approval, the status of the loan is changed to "approved." This signifies that the funds have been successfully transferred and that the loan agreement is now in effect.
Keeper method
package keeper
import (
"context"
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)
loan, found := k.GetLoan(ctx, msg.Id)
if !found {
return nil, sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, "key %d doesn't exist", msg.Id)
}
if loan.State != "requested" {
return nil, sdkerrors.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, sdkerrors.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
}
ApproveLoan
takes a context and a message of type *types.MsgApproveLoan
as
input, and returns a pointer to a types.MsgApproveLoanResponse
and an error
.
The function first retrieves a loan object by calling k.GetLoan(ctx, msg.Id)
,
where ctx
is a context object, k
is the msgServer
object, GetLoan
is a
method on k
, and msg.Id
is a field of the msg object passed as an argument.
If the loan is not found, it returns nil
and an error wrapped with
sdkerrors.ErrKeyNotFound
.
Next, the function checks if the loan's state is "requested"
. If it is not, it
returns nil
and an error wrapped with types.ErrWrongLoanState
.
If the loan's state is "requested"
, the function parses the addresses of the
lender and borrower from bech32 strings, and then parses the amount
of the
loan from a string. If there is an error parsing the coins in the loan amount,
it returns nil
and an error wrapped with types.ErrWrongLoanState
.
Otherwise, the function calls the SendCoins
method on the k.bankKeeper
object, passing it the context, the lender and borrower addresses, and the
amount of the loan. It then updates the lender field of the loan object and sets
its state to "approved"
. Finally, it stores the updated loan object by calling
k.SetLoan(ctx, loan)
.
At the end, the function returns a types.MsgApproveLoanResponse
object and
nil
for the error.
Register a custom error
To register the custom error ErrWrongLoanState
that is used in the
ApproveLoan
function, modify the "errors.go" file:
package types
import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
var (
ErrWrongLoanState = sdkerrors.Register(ModuleName, 2, "wrong loan state")
)