Contractless/docs/LOAN_TRANSACTIONS.md

19 KiB

Loan Transactions

Contractless loans are native two-party loan contracts. They do not use a smart-contract VM, and they are not simple wallet notes. A confirmed loan contract moves real balances on chain:

  • The lender's loan asset moves to the borrower.
  • The borrower's collateral moves into a chain-tracked collateral holding balance.
  • Later loan payments move repayment value back to the lender.
  • A collateral claim closes the contract by moving the collateral either back to the borrower or to the lender.

Loans are one of the most unique transaction categories in Contractless. This guide explains how the loan contract, loan payment, and collateral claim transactions work together.

On Windows, add .exe to each command name.

When a tool asks for a wallet path or transaction file path, press <Tab> to search and auto-complete files and folders.

CLI Tools

Tool Purpose
create_loan_tx Creates the lender-signed loan offer.
verify_sign_loan_tx Lets the borrower review terms, second-sign the loan, and save the completed contract.
create_loan_payment_tx Creates a borrower payment transaction for an active loan.
create_collateral_claim_tx Creates a collateral claim transaction. Used by either borrower or lender depending on contract state.
lookup_loan_by_address Lists loan contracts involving a wallet address.
lookup_loan_by_hash Looks up one loan contract by contract hash.

Creation tools save signed transaction JSON under:

./transactions/<hash>.json

Saving a transaction file does not broadcast it. Submit completed transactions with broadcast_transaction or with the GUI wallet import/broadcast flow.

Three Transaction Types

Loans use three native transaction types:

Transaction Type Who Signs What It Does
Loan contract 7 Lender and borrower Creates the loan, disburses the loaned asset, and locks collateral.
Loan payment 8 Borrower Pays some or all of the scheduled repayment balance.
Collateral claim 9 Borrower or lender Returns collateral to borrower after full repayment, or transfers collateral to lender when claim rules are met.

Loan Lifecycle

  1. The lender creates a loan offer with create_loan_tx.
  2. The lender sends the saved JSON file to the borrower.
  3. The borrower reviews and signs the loan with verify_sign_loan_tx.
  4. The completed loan contract is broadcast.
  5. When the loan confirms, the loaned asset moves from lender to borrower.
  6. At the same time, collateral moves from borrower to a collateral holding balance.
  7. The borrower makes one or more payments with create_loan_payment_tx.
  8. When fully paid, the borrower uses create_collateral_claim_tx to reclaim collateral.
  9. If the borrower becomes delinquent enough, the lender uses create_collateral_claim_tx to claim collateral.

Loan Contract Creation

Use create_loan_tx to create the lender side of a loan.

Usage:

create_loan_tx

The active wallet becomes the lender. The output is only partially signed. The borrower must review and sign it before it can be broadcast.

Loan Contract Fields

Field Size Meaning
txtype 1 byte Transaction type. For loan contracts this is 7.
timestamp 4 bytes Loan start timestamp. Created from the entered start date at UTC midnight.
loan_coin 15 bytes Base coin or token being lent, padded to 15 bytes.
loan_amount 8 bytes Amount lent, in atomic units.
lender 22 bytes Lender short address.
collateral 21 bytes Base coin, token, or numbered NFT collateral field.
collateral_amount 8 bytes Collateral amount in atomic units. For NFT collateral, use 1.
borrower 22 bytes Borrower short address.
payment_period 1 byte d, w, or m for daily, weekly, or monthly.
payment_number 1 byte Total number of scheduled payments.
payment_amount 8 bytes Amount due per scheduled payment, in atomic units.
grace_period 1 byte Number of overdue payments allowed before normal lender claim can become possible.
max_late_value 8 bytes Overdue value threshold for normal lender collateral claim.
txfee 8 bytes Lender base-currency transaction fee. Minimum is 3 CLC or CLTC.
hash 32 bytes Hash of the unsigned loan contract payload.
signature1 666 bytes Lender signature.
signature2 666 bytes Borrower signature. Present only after borrower signs.

Prompts

create_loan_tx asks for:

Prompt What To Enter
Loan coin/token Base coin or existing token being lent.
Loan amount Amount lent in display units.
Payment period daily, weekly, or monthly.
Payment number Number of scheduled payments required.
Payment amount Amount due each payment period.
Grace period How many overdue payments are allowed before normal lender claim can become possible.
Max late value How far behind in value the borrower may be before normal lender claim can become possible.
Collateral coin/token/NFT Base coin, token, or NFT collateral. Numbered NFTs use the name_##### form.
Collateral amount Amount of collateral. Enter 1 for NFT collateral.
Start date Loan start date as YYYY-MM-DD. Stored as UTC midnight for that date.
Wallet path Lender wallet path.
Wallet key Lender wallet decryption key.
Borrower address Borrower short address or vanity address.
Transaction fee Minimum 3 CLC or CLTC.

Loan Creation Rules

A loan contract is valid only when:

  • Both lender and borrower addresses are registered and valid.
  • Lender and borrower both sign the exact same loan hash.
  • The lender has enough of the loan asset to fund the loan.
  • The lender has enough base currency for the loan creation fee.
  • The borrower has enough collateral.
  • The loan asset exists as base currency or a token.
  • The collateral exists as base currency, a token, or an NFT.
  • payment_period is d, w, or m.
  • payment_amount is not greater than loan_amount.
  • payment_amount * payment_number is at least the loan_amount.
  • max_late_value is not greater than loan_amount.
  • grace_period is not greater than payment_number.
  • The contract is broadcast within 30 days of the stored timestamp.

What Happens When The Loan Confirms

When a valid loan contract is mined:

  • The lender pays the base-currency fee to the miner.
  • The loaned asset moves from lender to borrower.
  • The collateral moves from borrower to a collateral holding balance named from the contract hash.
  • The contract is indexed for both lender and borrower.
  • The loan is marked active.

The collateral is not held by the lender while the loan is active. It is held by the chain under a derived collateral holding balance.

Borrower Review And Second Signature

The borrower signs the lender-created file with verify_sign_loan_tx.

Usage:

verify_sign_loan_tx <path/to/file.json>

The tool:

  1. Loads the lender-signed loan JSON.
  2. Loads the borrower wallet.
  3. Confirms the active wallet is the borrower in the contract.
  4. Rebuilds the loan hash from the JSON fields.
  5. Shows the borrower human-readable questions about the loan terms.
  6. Signs only if the rebuilt hash matches the lender's hash.
  7. Saves the completed two-signature loan contract JSON.

The borrower is asked to confirm:

  • Amount and asset they expect to receive.
  • Collateral amount and asset they agree to lock.
  • Payment period.
  • Total number of payments.
  • Amount of each payment.
  • Grace period.
  • Max late value.
  • Start date.
  • Lender wallet address.

After borrower signing, the output contains both signature1 and signature2 and can be broadcast.

Payment Schedule

Loan schedules are based on the loan timestamp, which is created from the start date at UTC midnight.

Payment periods:

Code Meaning First Payment Due
d Daily 1 day after start date
w Weekly 7 days after start date
m Monthly 1 calendar month after start date

A payment is not overdue until the full due date has passed in UTC.

Example:

Start date: March 15
Period: daily
First payment due: March 16
First payment overdue: March 17 at 00:00 UTC

Weekly works the same way, but with 7-day intervals.

Monthly payments are anchored to the original calendar day. If a month does not have that day, the due date uses the last day of that month.

Example:

Start date: January 31
First monthly due date: February 28, or February 29 in a leap year
Second monthly due date: March 31

Loan Payments

Use create_loan_payment_tx to create a borrower payment.

Usage:

create_loan_payment_tx

The transaction type is 8.

Loan Payment Fields

Field Size Meaning
txtype 1 byte Transaction type. For loan payments this is 8.
timestamp 4 bytes Payment creation timestamp.
payback_amount 8 bytes Amount paid toward the contract, in the loan asset atomic units.
contract_hash 32 bytes Hash of the loan contract being paid.
address 22 bytes Payer short address.
tip 8 bytes Miner tip paid in the loan asset. Must be at least 1% of payment amount.
txfee 8 bytes Base-currency transaction fee. Minimum is 0.01 CLC or CLTC.
hash 32 bytes Hash of the payment transaction.
signature 666 bytes Payer signature.

Payment Prompts

create_loan_payment_tx asks for:

Prompt What To Enter
Loan contract hash Contract hash of the loan being paid.
Payment amount Amount paid toward the loan in display units.
Miner tip Tip in the loan asset. Must be at least 1% of payment amount.
Fee Minimum 0.01 CLC or CLTC.
Wallet path Borrower wallet path.
Wallet key Borrower wallet decryption key.

Payment Rules

Payments are flexible:

  • The borrower may make partial payments.
  • The borrower may pay more than one scheduled payment at once.
  • The borrower may pay the full remaining balance early.

But payments cannot exceed the remaining contract balance. The node also checks pending loan payments in the mempool so multiple pending payments cannot collectively overpay the loan.

Payment totals are tracked by value, not by "number of payment transactions."

Example:

Scheduled payment amount: 210
Borrower sends five payments of 1
Total paid: 5
Completed scheduled payment value: 5 of 210

Those five small payments do not count as five full scheduled payments. They only reduce the overdue value by 5.

When a payment confirms:

  • The borrower pays the base-currency fee to the miner.
  • The borrower pays payback_amount of the loan asset to the lender.
  • The borrower pays tip of the loan asset to the miner.
  • The payment amount is appended to the contract payment history.

Collateral Claims

Use create_collateral_claim_tx to create a collateral claim.

Usage:

create_collateral_claim_tx

The transaction type is 9.

The same transaction type is used by:

  • Borrower reclaiming collateral after full repayment.
  • Lender claiming collateral after the borrower is sufficiently delinquent.

Collateral Claim Fields

Field Size Meaning
txtype 1 byte Transaction type. For collateral claims this is 9.
time / timestamp 4 bytes Claim creation timestamp.
contract_hash 32 bytes Hash of the loan contract.
address 22 bytes Claimant short address. Must be lender or borrower.
txfee 8 bytes Base-currency transaction fee. Minimum is 3 CLC or CLTC.
signature 666 bytes Claimant signature.

Claim Prompts

create_collateral_claim_tx asks for:

Prompt What To Enter
Loan contract hash Contract hash of the loan being claimed.
Fee Minimum 3 CLC or CLTC.
Wallet path Claimant wallet path.
Wallet key Claimant wallet decryption key.

Only the lender or borrower can claim collateral.

Borrower Collateral Reclaim

The borrower can reclaim collateral only after the loan is fully paid.

The full repayment requirement is:

payment_amount * payment_number

The borrower cannot reclaim collateral while any part of that scheduled total remains unpaid.

When borrower reclaim confirms:

  • The borrower pays the base-currency collateral claim fee to the miner.
  • Collateral moves from the collateral holding balance back to the borrower.
  • The loan is marked inactive.

Lender Collateral Claim

Lender collateral claims have two normal conditions:

  1. The borrower must be past the allowed missed-payment grace period.
  2. The overdue value must be greater than max_late_value.

Both normal conditions must be met. One condition alone is not enough.

Condition 1: Grace Period

The node calculates how many scheduled payments are overdue as of the claim time.

A payment only becomes overdue after the full UTC due date has passed.

The lender cannot claim while:

payments_due <= grace_period

The normal grace condition is met only when:

payments_due > grace_period

Example:

grace_period = 1
payments_due = 1
claim rejected

grace_period = 1
payments_due = 2
grace condition met

Condition 2: Overdue Value

The node calculates:

should_have_paid = payments_due * payment_amount
overdue_value = should_have_paid - total_paid

The normal overdue-value condition is met only when:

overdue_value > max_late_value

Equal is not enough.

Example:

max_late_value = 210
overdue_value = 210
claim rejected

max_late_value = 210
overdue_value = 211
claim allowed if grace condition is also met

This prevents collateral from being claimed merely because a scheduled due date passed. The borrower must be both late enough in time and behind enough in value.

Partial Payment Example

Assume:

payment_amount = 210
grace_period = 1
max_late_value = 210

If the borrower sends five payments of 1, total paid is 5.

After the first payment is overdue:

payments_due = 1
should_have_paid = 210
total_paid = 5
overdue_value = 205

The claim is rejected because:

  • payments_due <= grace_period
  • overdue_value <= max_late_value

After the second payment is overdue:

payments_due = 2
should_have_paid = 420
total_paid = 5
overdue_value = 415

The claim can be allowed because:

  • payments_due > grace_period
  • overdue_value > max_late_value

Final Term Plus Grace Rule

There is one special final closeout rule.

After the full loan term plus the allowed grace period has passed, any unpaid remaining balance allows the lender to claim collateral.

This rule exists to prevent a borrower from leaving a small final balance unpaid forever.

Example:

payment_amount = 100
payment_number = 5
grace_period = 1
max_late_value = 100
remaining_balance = 99

Under the normal overdue-value rule, 99 is not greater than 100, so the lender might never be able to claim collateral.

The final closeout rule fixes that:

full loan term + grace period has passed
remaining_balance > 0
lender can claim collateral

This final rule still has a time requirement. The lender must wait until the full schedule plus grace period has passed. What it ignores is the normal max_late_value threshold, because any unpaid amount after the final grace window means the loan was not fully repaid.

Lookup By Hash

Use lookup_loan_by_hash to inspect one loan contract.

Usage:

lookup_loan_by_hash <loan_hash>

The tool asks for a wallet path and wallet key for authenticated RPC handshake. The lookup does not spend funds.

Expected output includes:

{
  "contract": "loan_contract_hash",
  "status": "active",
  "creation_date": "06-30-26",
  "start_timestamp": 1782777600,
  "lender": "lender_short_address.cltc",
  "borrower": "borrower_short_address.cltc",
  "coin_loaned": "CLTC",
  "loaned_count": 1000.0,
  "loaned_count_atomic": 100000000000,
  "collateral": "tokenname",
  "collateral_count": 2000.0,
  "collateral_count_atomic": 200000000000,
  "payment_type": "daily",
  "number_of_payments": 5,
  "payment_value": 210.0,
  "payment_value_atomic": 21000000000,
  "max_late_payments": 1,
  "max_late_value": 210.0,
  "max_late_value_atomic": 21000000000,
  "total_payments_made": 1,
  "total_value_paid": 210.0,
  "total_value_paid_atomic": 21000000000,
  "pending_value": 0.0,
  "pending_value_atomic": 0,
  "remaining_balance": 840.0,
  "remaining_balance_atomic": 84000000000,
  "remaining_after_pending": 840.0,
  "remaining_after_pending_atomic": 84000000000,
  "collateral_claimed_by": "",
  "payments": [
    {
      "txid": "payment_txid",
      "amount": 210.0,
      "payee": "borrower_short_address.cltc",
      "date": "07-01-26"
    }
  ]
}

Statuses:

Status Meaning
active Loan is active and not currently delinquent by due schedule.
delinquent Scheduled expected payments exceed confirmed paid value.
inactive Collateral has been claimed or returned.

pending_value is the total of pending mempool payments known to the node. It is shown for wallet/user awareness, but consensus validation of blocks uses confirmed payment history.

In the payment history, payee is the field name returned by the current lookup parser for the payment transaction address. In normal borrower payments, this is the borrower/payer address from the payment transaction.

Lookup By Address

Use lookup_loan_by_address to list loan contracts involving a wallet address.

Usage:

lookup_loan_by_address <wallet_address>

The address can be a short address or vanity address. The tool asks for a wallet path and wallet key for authenticated RPC handshake. The lookup does not spend funds.

Expected output:

{
  "address": "wallet_short_address.cltc",
  "contracts": 2,
  "loans": [
    {
      "contract": "loan_contract_hash",
      "status": "active",
      "lender": "lender_short_address.cltc",
      "borrower": "borrower_short_address.cltc",
      "payments": []
    }
  ]
}

Each loan entry uses the same summary fields as lookup_loan_by_hash.

Common Problems

Problem Likely Cause
Loan contract rejected Missing second signature, bad hash, invalid asset, insufficient lender balance, insufficient borrower collateral, fee below 3, bad payment schedule, or broadcast more than 30 days after timestamp.
Borrower cannot sign Active wallet is not the borrower, terms were changed after lender signed, or the borrower rejected one of the review questions.
Payment rejected Contract not active, contract hash is not a loan, payment exceeds remaining balance, pending payments would overpay, tip below 1%, fee below 0.01, or borrower lacks funds.
Borrower collateral reclaim rejected Loan is not fully paid.
Lender collateral claim rejected Grace period has not passed, overdue value is not greater than max_late_value, final closeout window has not passed, collateral already claimed, or fee is below 3.
Lookup returns no loan The contract is not confirmed, the hash is not a loan contract, or the queried address is not lender or borrower on any indexed contract.