1"use strict";(globalThis.webpackChunkmy_website=globalThis.webpackChunkmy_website||[]).push([[1395],{15680(e,n,t){t.d(n,{xA:()=>c,yg:()=>g});var r=t(96540);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){o(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var s=r.createContext({}),p=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c=function(e){var n=p(e.components);return r.createElement(s.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),g=o,y=u["".concat(s,".").concat(g)]||u[g]||d[g]||a;return t?r.createElement(y,i(i({ref:n},c),{},{components:t})):r.createElement(y,i({ref:n},c))}));function g(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var a=t.length,i=new Array(a);i[0]=u;var l={};for(var s in n)hasOwnProperty.call(n,s)&&(l[s]=n[s]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var p=2;p<a;p++)i[p]=t[p];return r.createElement.apply(null,i)}return r.createElement.apply(null,t)}u.displayName="MDXCreateElement"},83500(e,n,t){t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>p});var r=t(58168),o=(t(96540),t(15680));const a={},i="Cancel a loan",l={unversionedId:"guide/loan/cancel",id:"version-v0.27/guide/loan/cancel",title:"Cancel a loan",description:"As a borrower, you have the option to cancel a loan you have created if you no",source:"@site/versioned_docs/version-v0.27/02-guide/05-loan/07-cancel.md",sourceDirName:"02-guide/05-loan",slug:"/guide/loan/cancel",permalink:"/v0.27/guide/loan/cancel",draft:!1,tags:[],version:"v0.27",sidebarPosition:7,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Liquidate loan",permalink:"/v0.27/guide/loan/liquidate"},next:{title:"Play",permalink:"/v0.27/guide/loan/play"}},s={},p=[],c={toc:p};function d(e){let{components:n,...t}=e;return(0,o.yg)("wrapper",(0,r.A)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,o.yg)("h1",{id:"cancel-a-loan"},"Cancel a loan"),(0,o.yg)("p",null,'As a borrower, you have the option to cancel a loan you have created if you no\nlonger want to proceed with it. However, this action is only possible if the\nloan\'s current status is marked as "requested".'),(0,o.yg)("p",null,"If you decide to cancel the loan, the collateral tokens that were being held as\nsecurity for the loan will be transferred back to your account from the module\naccount. This means that you will regain possession of the collateral tokens you\nhad originally put up for the loan."),(0,o.yg)("pre",null,(0,o.yg)("code",{parentName:"pre",className:"language-go",metastring:'title="x/loan/keeper/msg_server_cancel_loan.go"',title:'"x/loan/keeper/msg_server_cancel_loan.go"'},'package keeper\n\nimport (\n "context"\n\n sdk "github.com/cosmos/cosmos-sdk/types"\n sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"\n\n "loan/x/loan/types"\n)\n\nfunc (k msgServer) CancelLoan(goCtx context.Context, msg *types.MsgCancelLoan) (*types.MsgCancelLoanResponse, error) {\n ctx := s
1dk.UnwrapSDKContext(goCtx)\n loan, found := k.GetLoan(ctx, msg.Id)\n if !found {\n return nil, sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, "key %d doesn\'t exist", msg.Id)\n }\n if loan.Borrower != msg.Creator {\n return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Cannot cancel: not the borrower")\n }\n if loan.State != "requested" {\n return nil, sdkerrors.Wrapf(types.ErrWrongLoanState, "%v", loan.State)\n }\n borrower, _ := sdk.AccAddressFromBech32(loan.Borrower)\n collateral, _ := sdk.ParseCoinsNormalized(loan.Collateral)\n err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, borrower, collateral)\n if err != nil {\n return nil, err\n }\n loan.State = "cancelled"\n k.SetLoan(ctx, loan)\n return &types.MsgCancelLoanResponse{}, nil\n}\n')),(0,o.yg)("p",null,(0,o.yg)("inlineCode",{parentName:"p"},"CancelLoan")," takes in two arguments: a ",(0,o.yg)("inlineCode",{parentName:"p"},"context.Context")," named ",(0,o.yg)("inlineCode",{parentName:"p"},"goCtx")," and a\npointer to a ",(0,o.yg)("inlineCode",{parentName:"p"},"types.MsgCancelLoan")," named ",(0,o.yg)("inlineCode",{parentName:"p"},"msg"),". It returns a pointer to a\n",(0,o.yg)("inlineCode",{parentName:"p"},"types.MsgCancelLoanResponse")," and an error."),(0,o.yg)("p",null,"The function begins by using the ",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.UnwrapSDKContext")," method to get the\n",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.Context")," from the ",(0,o.yg)("inlineCode",{parentName:"p"},"context.Context")," object. It then uses the ",(0,o.yg)("inlineCode",{parentName:"p"},"GetLoan"),"\nmethod of the ",(0,o.yg)("inlineCode",{parentName:"p"},"msgServer")," type to retrieve a loan identified by the ",(0,o.yg)("inlineCode",{parentName:"p"},"Id")," field\nof the ",(0,o.yg)("inlineCode",{parentName:"p"},"msg")," argument. If the loan is not found, the function returns an error\nusing the ",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.ErrKeyNotFound")," error wrapped with the ",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.Wrap")," method."),(0,o.yg)("p",null,"Next, the function checks if the ",(0,o.yg)("inlineCode",{parentName:"p"},"Creator")," field of the msg argument is the same\nas the ",(0,o.yg)("inlineCode",{parentName:"p"},"Borrower")," field of the loan. If they are not the same, the function\nreturns an error using the ",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.ErrUnauthorized")," error wrapped with the\n",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.Wrap")," method."),(0,o.yg)("p",null,"The function then checks if the ",(0,o.yg)("inlineCode",{parentName:"p"},"State")," field of the loan is equal to the string\n",(0,o.yg)("inlineCode",{parentName:"p"},'"requested"'),". If it is not, the function returns an error using the\ntypes.",(0,o.yg)("inlineCode",{parentName:"p"},"ErrWrongLoanState")," error wrapped with the ",(0,o.yg)("inlineCode",{parentName:"p"},"sdk.Wrapf")," method."),(0,o.yg)("p",null,"If the loan has the correct state and the creator of the message is the borrower\nof the loan, the function proceeds to send the collateral coins held in the\n",(0,o.yg)("inlineCode",{parentName:"p"},"Collateral")," field of the loan back to the borrower's account using the\n",(0,o.yg)("inlineCode",{parentName:"p"},"SendCoinsFromModuleToAccount")," method of the ",(0,o.yg)("inlineCode",{parentName:"p"},"bankKeeper"),'. The function then\nupdates the State field of the loan to the string "cancelled" and sets the\nupdated loan using the ',(0,o.yg)("inlineCode",{parentName:"p"},"SetLoan")," method. Finally, the function returns a\n",(0,o.yg)("inlineCode",{parentName:"p"},"types.MsgCancelLoanResponse")," object and a nil error."))}d.isMDXComponent=!0}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.