Borrowing
Repay Loan
Repay loan debt, interest first then principal
POST
/
lending-external-securities-v2
/
api
/
positions
/
{marketId}
/
repay
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/repay" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"loanId": 5, "all": true}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/repay`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, all: true })
});
const { data } = await res.json();
const hashes: string[] = [];
for (const step of data.steps) {
const tx = await wallet.sendTransaction(step.transaction);
await tx.wait();
hashes.push(tx.hash);
}
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, txHash: hashes[data.confirmStepIndex] })
});
{
"success": true,
"data": {
"success": true,
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x98ad0ca091552e23c564b41c74282e5343d03e8a",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Approve the market to pull USDC"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"gasLimit": "600000",
"value": "0",
"chainId": 11155111
},
"functionName": "repay"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x98ad0ca091552e23c564b41c74282e5343d03e8a",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Clear the leftover USDC allowance granted for this repayment"
}
],
"fullRepayment": true,
"confirmStepIndex": 1,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/repay",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
},
"gasLimitBasis": "simulated",
"permitSupported": true,
"outstandingDebt": "50412.881000",
"repayAmount": "50515.706763",
"transactionFee": {
"kind": "REPAY",
"fee": "2.0",
"feeRaw": "2000000",
"message": "This market charges a repayment fee of about 2.0 USDC on top of the debt, taken from the payment before it reduces the loan. The amount approved and offered covers the debt, the accrual buffer and the fee, and the market pulls only what closes the loan."
},
"warning": "This market charges a repayment fee of about 2.0 USDC on top of the debt, taken from the payment before it reduces the loan. The amount approved and offered covers the debt, the accrual buffer and the fee, and the market pulls only what closes the loan."
}
}
{
"success": true,
"data": {
"success": true,
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"gasLimit": "650000",
"value": "0",
"chainId": 11155111
},
"functionName": "repayWithPermit",
"description": "Repay in a single transaction: the embedded permit installs the allowance and the market pulls at most the true debt"
}
],
"gasLimitBasis": "simulated",
"fullRepayment": false,
"confirmStepIndex": 0,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/repay",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
},
"permitUsed": true,
"outstandingDebt": "50412.881000",
"repayAmount": "10000.0",
"transactionFee": {
"kind": "REPAY",
"fee": "2.0",
"feeRaw": "2000000",
"debtReduction": "9998.0",
"message": "This market charges a repayment fee of 2.0 USDC, taken from this payment first: 9998.0 USDC of it reduces the loan."
},
"warning": "This market charges a repayment fee of 2.0 USDC, taken from this payment first: 9998.0 USDC of it reduces the loan."
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"loanId": "5",
"repaidAmount": "50412.913422",
"collateralReturned": "1000.0",
"collateralReturnEscrowed": false
}
}
{
"success": false,
"error": {
"code": "PERMIT_VALUE_REQUIRED",
"message": "A full repayment with a permit needs permit.value: the permit is verified and encoded over that figure, and it must cover the outstanding debt at the moment the transaction mines. Quote it through the permit-quote endpoint (50515.706763 USDC now, the live debt plus a 20 bps accrual buffer and the repayment fee) and sign the permit over the value it names."
}
}
{
"success": false,
"error": {
"code": "TX_WRONG_TARGET",
"message": "This transaction neither targets the market nor emits a LoanRepaid from it. A full repayment is signed as several steps and only the repay step can be confirmed. Use the hash of the step whose functionName is \"repay\" (index 1 of the steps returned for this repayment), not the last one."
}
}
Repays part or all of a loan’s outstanding debt. Accrued interest is settled before principal. A repayment that clears the whole debt closes the loan in the same transaction and releases the collateral, so no Close Loan call follows it.
Anyone can repay any loan through the approve-then-repay steps, so a third party can rescue a position approaching liquidation. The single-transaction permit path is the borrower’s own. A repayment sent without a
Confirming with
signedPrice reads no price, so neither a stale price nor a paused market blocks it.
To close a loan, repay with
all: true. A payment of exactly the debt quoted earlier leaves the interest accrued since then outstanding. On a market with a repayment fee it also leaves a fee-sized remainder open. The loan then stays active and keeps accruing.Path Parameters
string
required
Body Parameters
integer
required
On-chain loan ID. A positive integer. Accepted as a JSON number or as a numeric string, so the value Get Loan returns passes straight back.
string
Amount to pay, as a positive decimal string in borrow asset units. The contract caps the payment at the debt plus the repayment fee, so overpaying does not transfer more than that. An amount that covers the current debt plus the repayment fee closes the loan, so it is built as a full repayment:
fullRepayment is true, a CUSTODY loan carries collateralRelease when the collateral would be escrowed, and a last step clears the leftover allowance. Required unless all is true or you are confirming with txHash.boolean
Repay the loan in full. The API reads the current debt and adds a 20 basis point accrual buffer plus the repayment fee to the offer. Interest accruing between the quote and the mine therefore cannot leave dust behind. Use this instead of computing a payoff yourself.
object
EIP-712 signed price from Sign Price, carried on-chain by the repayment. A repayment is the most frequent transaction a market sees, so carrying a price here keeps the oracle fresh without a separate write. Omit it and the repayment stays on the entry point that no price can block, which is the path a borrower must always have. It is not carried on the permit path. A market that prices from an external feed refuses a signed price with
EXTERNAL_FEED_ACTIVE, and a market with a fixed price with FIXED_PRICE_ACTIVE, because neither oracle takes one. Leave it out there.object
An EIP-2612 permit over the settlement asset, signed by the borrower with the market as spender. It replaces the approval, so the repayment is one transaction. Get the payload to sign from Get Permit Quote. See Pay with a permit for the binding rules.
Show child attributes
Show child attributes
integer
required
Unix timestamp in seconds that the permit was signed with. It must still be in the future.
integer
required
Signature recovery id,
27 or 28.string
required
32 bytes, hex.
string
required
32 bytes, hex.
string
The amount the permit was signed over, as a decimal string in borrow asset units. Required with
all: true. With amount it may be omitted, and when sent it must equal amount.string
Hash of the transaction you broadcast for this operation. Send it to confirm the transaction and record the result. Omit it to receive the calldata.
Repayment fee
A market may carry a flat repayment fee, stamped when it was deployed and never changeable afterwards. Read it fromtransactionFees on Get Fee Split. The payer bears it. The fee comes out of the payment first, and only the rest reduces the debt.
Each charge is capped at 0.5 percent of the debt it discharges. The contract caps a payment at the debt plus min(repayFee, debt / 200), which is exactly what closes the loan. A partial payment reduces the debt by the payment less a fee of at most one 201st of it. When the fee is not zero, the calldata response carries transactionFee and states the effect in warning.
Pay with a permit
The permit path exists only where the settlement asset provably implements EIP-2612.permitSupported on the standard response says whether this market’s asset qualifies. It is probed once per settlement asset and stored on the market, not asked per request. A token with a different permit shape, such as DAI’s, reads as unsupported, and a permit sent to it is refused with PERMIT_UNSUPPORTED.
The permit must be signed by the loan’s borrower, name the market as spender, and carry the token’s current nonce and a future deadline. The borrower’s wallet also sends the transaction, because the market redeems the permit for the sender. A third party repays through the approve-then-repay steps instead.
repayWithPermit binds the permit to the amount it repays, so the signed value decides what the calldata carries:
- With
amount, the permit covers exactlyamount. Apermit.valuethat differs is refused withINVALID_PERMIT. - With
all: true,permit.valueis required, or the call returnsPERMIT_VALUE_REQUIRED. It becomes the amount the calldata offers, and it must cover the live debt plus the repayment fee, or the call returnsINVALID_PERMIT. - A full-repayment value inside the 20 basis point buffer builds with a
warning. If interest outgrows it before the transaction mines, the market takes the permit’s value as a partial repayment and the loan stays open.
INVALID_PERMIT. When the token’s domain or the nonce cannot be read, the call returns PERMIT_UNVERIFIABLE.
Transaction Shape
A partial repayment returns two steps:approve on the borrow asset, then repay.
A full repayment (all: true) returns three. The third resets the allowance to zero. repay caps the pull at what closes the loan, so without it the unused approval would stay live against the payer’s funds after the loan closed.
With a permit, the approval disappears. A partial repayment is one step, repayWithPermit. A full repayment is two: repayWithPermit, then the same allowance reset, because the permit installs the whole signed value as an allowance and the repayment does not spend all of it.
The repay and repayWithPermit steps carry a gasLimit sized from a simulation of the sequence you sign, run from the borrower’s wallet: the approval and then the repayment, or the permit call alone. The limit is the gas the simulated repayment used plus 50 percent, and never below 600000 for repay or 650000 for repayWithPermit. A repayment that uses less than two thirds of the floor therefore still carries the floor. gasLimitBasis says how it was set:
simulated: the sequence was simulated and the repayment succeeded in it.floor: the sequence could not be simulated, or the repayment did not succeed in it, so the step carries the floor. Estimate the repayment’s gas once the approval is mined, and use the larger of that estimate andgasLimit.
The confirmable step is not always the last one, and it is not always at the same index. Read
confirmStepIndex from the response rather than assuming a position. It is 1 on the approve-then-repay path and 0 on the permit path, and in both cases it names the step whose functionName starts with repay. Confirming with the allowance-reset hash returns TX_WRONG_TARGET.Response Fields
object
Show child attributes
Show child attributes
boolean
true, nested inside data on the calldata response.string
SIGN_TRANSACTIONS. Returned when txHash is omitted.array
Ordered transactions to broadcast. Returned when
txHash is omitted.boolean
Whether the payload settles the loan in full:
all: true, or an amount that covers the current debt plus the repayment fee.integer
Index of the step to confirm with.
1 on the approve-then-repay path, 0 on the permit path. Read it rather than assuming.string
How the repay step’s
gasLimit was set: simulated (the gas the simulated sequence used plus 50 percent, never below the floor) or floor (600000, or 650000 for repayWithPermit, when the sequence could not be simulated). See Transaction Shape.object
{ endpoint, field, body } on both paths: this route, txHash as the field, and a body carrying loanId with txHash: null.boolean
Whether the settlement asset implements EIP-2612, so a
permit could have been sent instead. Present on the approve-then-repay path.boolean
true on the permit path. Absent otherwise.string
Principal plus accrued interest at the time the payload was built, without the repayment fee.
string
Amount the repay step offers. On a full repayment it includes the accrual buffer and the fee. On the permit path it is the permit’s value.
object
The repayment fee, present only when it is not zero. Carries
kind: "REPAY", fee, feeRaw and message, plus debtReduction on a partial repayment. On a full repayment fee is computed on the debt at build time.object
Present on a full repayment (
fullRepayment: true) of a CUSTODY loan when the collateral token would refuse to return the collateral, or when its verdict cannot be read. The repayment still succeeds, and the adapter escrows the collateral instead of delivering it.string
One string joining whichever apply: the permit headroom warning, the fee message and the collateral release message.
string
Transaction hash. Returned when confirming.
string
Loan ID, echoed back as a string. Returned when confirming.
string
Principal plus interest the payment settled, read from the
LoanRepaid event rather than from the calldata. It excludes the repayment fee. On a full repayment it is lower than repayAmount, because the contract pulls only what closes the loan. Returned when confirming.string
Collateral released when the repayment closed the loan. Present only then. Returned when confirming.
boolean
true when that return was blocked on compliance and escrowed on the adapter instead of delivered. Claim it with Claim Escrowed Collateral.curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/repay" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"loanId": 5, "all": true}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/repay`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, all: true })
});
const { data } = await res.json();
const hashes: string[] = [];
for (const step of data.steps) {
const tx = await wallet.sendTransaction(step.transaction);
await tx.wait();
hashes.push(tx.hash);
}
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, txHash: hashes[data.confirmStepIndex] })
});
{
"success": true,
"data": {
"success": true,
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x98ad0ca091552e23c564b41c74282e5343d03e8a",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Approve the market to pull USDC"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"gasLimit": "600000",
"value": "0",
"chainId": 11155111
},
"functionName": "repay"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x98ad0ca091552e23c564b41c74282e5343d03e8a",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Clear the leftover USDC allowance granted for this repayment"
}
],
"fullRepayment": true,
"confirmStepIndex": 1,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/repay",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
},
"gasLimitBasis": "simulated",
"permitSupported": true,
"outstandingDebt": "50412.881000",
"repayAmount": "50515.706763",
"transactionFee": {
"kind": "REPAY",
"fee": "2.0",
"feeRaw": "2000000",
"message": "This market charges a repayment fee of about 2.0 USDC on top of the debt, taken from the payment before it reduces the loan. The amount approved and offered covers the debt, the accrual buffer and the fee, and the market pulls only what closes the loan."
},
"warning": "This market charges a repayment fee of about 2.0 USDC on top of the debt, taken from the payment before it reduces the loan. The amount approved and offered covers the debt, the accrual buffer and the fee, and the market pulls only what closes the loan."
}
}
{
"success": true,
"data": {
"success": true,
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"gasLimit": "650000",
"value": "0",
"chainId": 11155111
},
"functionName": "repayWithPermit",
"description": "Repay in a single transaction: the embedded permit installs the allowance and the market pulls at most the true debt"
}
],
"gasLimitBasis": "simulated",
"fullRepayment": false,
"confirmStepIndex": 0,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/repay",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
},
"permitUsed": true,
"outstandingDebt": "50412.881000",
"repayAmount": "10000.0",
"transactionFee": {
"kind": "REPAY",
"fee": "2.0",
"feeRaw": "2000000",
"debtReduction": "9998.0",
"message": "This market charges a repayment fee of 2.0 USDC, taken from this payment first: 9998.0 USDC of it reduces the loan."
},
"warning": "This market charges a repayment fee of 2.0 USDC, taken from this payment first: 9998.0 USDC of it reduces the loan."
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"loanId": "5",
"repaidAmount": "50412.913422",
"collateralReturned": "1000.0",
"collateralReturnEscrowed": false
}
}
{
"success": false,
"error": {
"code": "PERMIT_VALUE_REQUIRED",
"message": "A full repayment with a permit needs permit.value: the permit is verified and encoded over that figure, and it must cover the outstanding debt at the moment the transaction mines. Quote it through the permit-quote endpoint (50515.706763 USDC now, the live debt plus a 20 bps accrual buffer and the repayment fee) and sign the permit over the value it names."
}
}
{
"success": false,
"error": {
"code": "TX_WRONG_TARGET",
"message": "This transaction neither targets the market nor emits a LoanRepaid from it. A full repayment is signed as several steps and only the repay step can be confirmed. Use the hash of the step whose functionName is \"repay\" (index 1 of the steps returned for this repayment), not the last one."
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
NO_MARKET_ADDRESS | 400 | The market has no on-chain address recorded |
MISSING_MARKET_ID | 400 | marketId is longer than 100 characters |
VALIDATION_ERROR | 400 | loanId is not a positive integer, neither amount nor all was supplied, an amount is malformed or carries more decimal places than the borrow asset supports, or a permit field has the wrong shape |
NO_OUTSTANDING_DEBT | 400 | all was set on a loan that owes nothing |
LOAN_NOT_ACTIVE | 400 | The loan is closed and can no longer be modified |
INVALID_PERMIT | 400 | permit.deadline is not in the future, permit.value breaks the binding rules, or the signature does not recover to the borrower for this spender, value, nonce and deadline |
PERMIT_VALUE_REQUIRED | 400 | A permit was sent with all: true but without permit.value |
INVALID_SIGNED_PRICE | 400 | The signedPrice is malformed, expired, dated in the future or older than the oracle’s price age window, or it was signed by a wallet that is not an authorized signer on the market’s oracle, which details.signer then names. Sign a fresh quote, or repay without it |
PRICE_DEVIATION_TOO_LARGE | 400 | The signedPrice moves further from the oracle’s current price than its maxDeviationBps allows |
PRICE_WINDOW_DEVIATION_TOO_LARGE | 400 | The signedPrice falls outside the band the oracle accepts within its current one-hour window |
TX_WRONG_TARGET | 400 | The confirmed transaction neither targets the market nor emits LoanRepaid from it. On a full repayment, confirm the repay step |
TX_NOT_VERIFIED | 400 | The confirmed transaction repays a different loan |
REPAY_FAILED | 400 | The repayment could not be prepared and no more specific code applied |
LOAN_NOT_FOUND | 404 | No such loan on this market |
MARKET_NOT_FOUND | 404 | No market with this ID on your instance |
PERMIT_UNSUPPORTED | 409 | A permit was sent for a settlement asset that does not implement EIP-2612, or whose support could not be verified. Use the approve-then-repay steps |
EXTERNAL_FEED_ACTIVE | 409 | A signedPrice was sent to a market that prices from an external feed. Retry without it |
FIXED_PRICE_ACTIVE | 409 | A signedPrice was sent to a market with a fixed price. Retry without it |
SIGNED_PRICE_OUTDATED | 409 | The signedPrice is not dated after the price the oracle already holds, so the oracle would refuse it. Sign a fresh quote, or repay without it |
LOAN_STATE_UNAVAILABLE | 503 | The loan could not be read from the network right now. Retry shortly |
MARKET_STATE_UNAVAILABLE | 503 | The market’s transaction fees could not be read, or, with a signedPrice, its price oracle. Retry shortly |
PRICE_STATE_UNAVAILABLE | 503 | The oracle could not be read to check the signedPrice, so nothing was built. Retry shortly, or repay without it |
PERMIT_UNVERIFIABLE | 503 | The settlement asset’s permit domain or the borrower’s nonce could not be read, so the signature could not be checked. Retry, or use the approve-then-repay steps |
txHash can also return any transaction verification error.⌘I
curl -X POST "https://api.trusset.org/lending-external-securities-v2/api/positions/{marketId}/repay" \
-H "X-API-Key: trusset_your_key_here" \
-H "Content-Type: application/json" \
-d '{"loanId": 5, "all": true}'
const url = `https://api.trusset.org/lending-external-securities-v2/api/positions/${marketId}/repay`;
const headers = {
'X-API-Key': 'trusset_your_key_here',
'Content-Type': 'application/json'
};
const res = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, all: true })
});
const { data } = await res.json();
const hashes: string[] = [];
for (const step of data.steps) {
const tx = await wallet.sendTransaction(step.transaction);
await tx.wait();
hashes.push(tx.hash);
}
await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ loanId: 5, txHash: hashes[data.confirmStepIndex] })
});
{
"success": true,
"data": {
"success": true,
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x98ad0ca091552e23c564b41c74282e5343d03e8a",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Approve the market to pull USDC"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"gasLimit": "600000",
"value": "0",
"chainId": 11155111
},
"functionName": "repay"
},
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x98ad0ca091552e23c564b41c74282e5343d03e8a",
"data": "0x...",
"value": "0",
"chainId": 11155111
},
"functionName": "approve",
"description": "Clear the leftover USDC allowance granted for this repayment"
}
],
"fullRepayment": true,
"confirmStepIndex": 1,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/repay",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
},
"gasLimitBasis": "simulated",
"permitSupported": true,
"outstandingDebt": "50412.881000",
"repayAmount": "50515.706763",
"transactionFee": {
"kind": "REPAY",
"fee": "2.0",
"feeRaw": "2000000",
"message": "This market charges a repayment fee of about 2.0 USDC on top of the debt, taken from the payment before it reduces the loan. The amount approved and offered covers the debt, the accrual buffer and the fee, and the market pulls only what closes the loan."
},
"warning": "This market charges a repayment fee of about 2.0 USDC on top of the debt, taken from the payment before it reduces the loan. The amount approved and offered covers the debt, the accrual buffer and the fee, and the market pulls only what closes the loan."
}
}
{
"success": true,
"data": {
"success": true,
"action": "SIGN_TRANSACTIONS",
"steps": [
{
"action": "SIGN_TRANSACTION",
"transaction": {
"to": "0x70a0e25c7b768b87e658348b3b577678a173e038",
"data": "0x...",
"gasLimit": "650000",
"value": "0",
"chainId": 11155111
},
"functionName": "repayWithPermit",
"description": "Repay in a single transaction: the embedded permit installs the allowance and the market pulls at most the true debt"
}
],
"gasLimitBasis": "simulated",
"fullRepayment": false,
"confirmStepIndex": 0,
"confirmWith": {
"endpoint": "POST /lending-external-securities-v2/api/positions/cmssh7p1k0001cghxq2m4v8rz/repay",
"field": "txHash",
"body": { "loanId": "5", "txHash": null }
},
"permitUsed": true,
"outstandingDebt": "50412.881000",
"repayAmount": "10000.0",
"transactionFee": {
"kind": "REPAY",
"fee": "2.0",
"feeRaw": "2000000",
"debtReduction": "9998.0",
"message": "This market charges a repayment fee of 2.0 USDC, taken from this payment first: 9998.0 USDC of it reduces the loan."
},
"warning": "This market charges a repayment fee of 2.0 USDC, taken from this payment first: 9998.0 USDC of it reduces the loan."
}
}
{
"success": true,
"data": {
"txHash": "0x9f2c41d8b7e05a3164c2870fbd935e1a4c7802db6135ea9048f7c21b5d3ea41b",
"loanId": "5",
"repaidAmount": "50412.913422",
"collateralReturned": "1000.0",
"collateralReturnEscrowed": false
}
}
{
"success": false,
"error": {
"code": "PERMIT_VALUE_REQUIRED",
"message": "A full repayment with a permit needs permit.value: the permit is verified and encoded over that figure, and it must cover the outstanding debt at the moment the transaction mines. Quote it through the permit-quote endpoint (50515.706763 USDC now, the live debt plus a 20 bps accrual buffer and the repayment fee) and sign the permit over the value it names."
}
}
{
"success": false,
"error": {
"code": "TX_WRONG_TARGET",
"message": "This transaction neither targets the market nor emits a LoanRepaid from it. A full repayment is signed as several steps and only the repay step can be confirmed. Use the hash of the step whose functionName is \"repay\" (index 1 of the steps returned for this repayment), not the last one."
}
}
