# Collateral-Free Integration Guide

> This tutorial was written for SDK version `6.0.0`.

![reNFT collateral-free contract flows](/files/18HUCzSwTvkM1RT33qJf)

### Lending and Renting NFTs[​](https://docs.renft.io/docs/Developers/collateral-free#lendrent-nfts-in-app) <a href="#lendrent-nfts-in-app" id="lendrent-nfts-in-app"></a>

To interact with our smart contracts, we always recommend using our [SDK](https://github.com/re-nft/sdk). We view the SDK as the source of truth for all of our deployments and business logic; most importantly, it versions where our smart contracts reside in the metaverse and defines objectively how they work.

To work with collateral-free lendings, we'd use the `Sylvester` contract:

```typescript
import {
  getRenftContract,
  DEPLOYMENT_SYLVESTER_ETHEREUM_MAINNET_V0,
  SylvesterV0FunctionInterface,
} from "@renft/sdk";

import { ethers } from "ethers";

const signer = ethers.Wallet.createRandom(); // In practical dApps, this would be the user's wallet!

const renft: SylvesterV0FunctionInterface = getRenftContract({
  deployment: DEPLOYMENT_SYLVESTER_ETHEREUM_MAINNET_V0,
  signer,
});
```

> 💭 We name our contracts after famous cats! You can find the name mappings [here](/developers/renft-contracts-addresses.md). Meow!

### Batching[​](https://docs.renft.io/docs/Developers/collateral-free#batching) Transactions <a href="#batching" id="batching"></a>

Any of the following functions support batching. This is shown below for the `lend()` instruction, where the user lends an [AstroCat](https://opensea.io/collection/renftlabs) and a [CatPlsr](https://opensea.io/assets?search\[query]=CatPlsr) within the *same function call*:

```typescript
import { NFTStandard, PaymentToken, packPrice } from "@renft/sdk";

const astroCatLendingArgs = [
  NFTStandard.E1155,
  "0x0db8c099b426677f575d512874d45a767e9acc3c",
  "1",
  1,
  1,
  packPrice("1"),
  PaymentToken.WETH,
];

const catPlsrLendingArgs = [
  NFTStandard.E1155,
  "0x0db8c099b426677f575d512874d45a767e9acc3c",
  "2",
  1,
  1,
  packPrice("0.5"),
  PaymentToken.WETH,
];

const lendingArgs = astroCatLendingArgs.map((value, index) => 
  [value, catPlsrLendingArgs[index]]
);

await renft.lend(...lendingArgs);
```

### Lending <a href="#lend" id="lend"></a>

dApps invoke `lend()` when they wish to create a new on-chain lending. A lending is when a market maker asserts that they wish to allow other users to temporarily have rights to the asset for the duration of the rental.

Since the `lend()` function is designed to batch multiple NFTs together, you can create a single-element lending by using single-element arrays for each of the required parameters:

```typescript
import { NFTStandard, PaymentToken, packPrice } from "@renft/sdk";

const nftStandard = NFTStandard.E1155;
const nftAddress = "0x0db8c099b426677f575d512874d45a767e9acc3c";
const tokenID = "1";
const lendAmount = 1; // Quantity of the NFT to lend.
const maxRentDuration = 1; // Duration is measured in days.
const dailyRentPrice = packPrice("1"); // Create a properly formatted rental price.
const paymentToken = PaymentToken.WETH;

await renft.lend(
  [nftStandard],
  [nftAddress],
  [tokenID],
  [lendAmount],
  [maxRentDuration],
  [dailyRentPrice],
  [paymentToken]
);
```

### Rent[​](https://docs.renft.io/docs/Developers/collateral-free#rent)ing <a href="#rent" id="rent"></a>

A renting is created when a user discovers a compelling lending on the blockchain and decides to take the maker up on their offer. In this instance, the user is the *taker* of the lending. Much like the previous example, we call the `rent()` function with vectorized data representing each individual token to be rented in a gas-optimized batch.

```typescript
import { NFTStandard } from "@renft/sdk";

const nftStandard = NFTStandard.E1155;
const nftAddress = "0x0db8c099b426677f575d512874d45a767e9acc3c";
const tokenID = "1";
const lendingID = "1"; // this information is pulled from the subgraph
const rentDuration = 1; // in days
const rentAmount = 1;

await renft.rent(
  [nftStandard],
  [nftAddress],
  [tokenID],
  [lendingID],
  [rentDuration],
  [rentAmount]
);
```

### Stopping a Rental <a href="#stop-rent" id="stop-rent"></a>

For a non-collateralized rental, even though no *real* possession of the NFT is given (it is a virtualized rights-to-ownership), the renter must signal that they have concluded "using" the NFT with a call to `stopRent()`.

If the renter fails to make this call, the lender is permitted to invoke `claimRent()`, explained in the following section, to redeem the full amount of rent.

> 💭 Invocations to `stopLend()` are disabled until the lender calls `claimRent()` first.[​](https://docs.renft.io/docs/Developers/collateral-free#stop-rent)

```typescript
import { NFTStandard } from "@renft/sdk";

const nftStandard = NFTStandard.E1155;
const nftAddress = "0x0db8c099b426677f575d512874d45a767e9acc3c";
const tokenID = "1";
const lendingID = "1"; // from subgraph
const rentingID = "1"; // from subgraph

await renft.stopRent(
  [nftStandard],
  [nftAddress],
  [tokenID],
  [lendingID],
  [rentingID],
);
```

### Claiming Rent[​](https://docs.renft.io/docs/Developers/collateral-free#claim-rent) <a href="#claim-rent" id="claim-rent"></a>

Lenders can claim rent by calling the `claimRent()` function.

Remember, the smart contract enforces the rules of lending and renting; you can try to claim the rent of an ongoing lending which doesn't belong to you, but the transaction will be reverted!

```typescript
import { NFTStandard } from "@renft/sdk";

const nftStandard = NFTStandard.E1155;
const nftAddress = "0x0db8c099b426677f575d512874d45a767e9acc3c";
const tokenID = "1";
const lendingID = "1";
const rentingID = "1";

await renft.claimRent(
  [nftStandard],
  [nftAddress],
  [tokenID],
  [lendingID],
  [rentingID],
);
```

### Stopping a Lending[​](https://docs.renft.io/docs/Developers/collateral-free#stop-lend) <a href="#stop-lend" id="stop-lend"></a>

Finally, there's the `stopLend` function, which is called by the lender. This prevents the provided assets from being rented out any longer, much to the chagrin of prospective renters.

```typescript
import { NFTStandard } from "@renft/sdk";

const nftStandard = NFTStandard.E1155;
const nftAddress = "0x0db8c099b426677f575d512874d45a767e9acc3c";
const tokenID = "1";
const lendingID = "1";

await renft.stopLend(
  [nftStandard],
  [nftAddress],
  [tokenID],
  [lendingID],
);
```

> To learn about more about how we determine the status of a particular lending or renting, check out [this guide](/developers/querying-renfts-on-chain-data.md)!

### How to unpack data?[​](https://docs.renft.io/docs/Developers/collateral-free#unpacking-data) <a href="#unpacking-data" id="unpacking-data"></a>

In reNFT, prices are returned in a custom format. This is a performance optimization which enables an entire lending to fit snugly inside a single storage slot, which saves gas.

To unpack them, we can use the `unpackPrice()` function:

```typescript
import { PaymentToken, unpackPrice } from "@renft/sdk";

// Convert a low-level representation of an ERC-20 used on
// the marketplace into a TypeScript-friendly enum.
const parsePaymentToken = (tkn: string): PaymentToken => {
  switch (tkn) {
    case "0":
      return PaymentToken.SENTINEL;
    case "1":
      return PaymentToken.WETH;
    case "2":
      return PaymentToken.DAI;
    case "3":
      return PaymentToken.USDC;
    case "4":
      return PaymentToken.USDT;
    case "5":
      return PaymentToken.TUSD;
    default:
      return PaymentToken.DAI;
  }
};

// In this example, let's imagine we've read Lending collection data
// from a Sylvester subgraph. Here's how we'd transform the low-level
// blockchain data into high-level, human (and feline) friendly types.
const lendingsDataToLendings = (
  theGraphLendings: TheGraphLending[]
) => {
  const theGraphToLending = (theGraphLending: TheGraphLending) => {
    return {
      lendingID: theGraphLending.id,
      lenderAddress: theGraphLending.lenderAddress,
      // Convert the price back into a BigNumber.
      dailyRentPrice: unpackPrice(theGraphLending.dailyRentPrice),
      maxRentDuration: Number(theGraphLending.maxRentDuration),
      lendAmount: Number(theGraphLending.lendAmount),
      paymentToken: parsePaymentToken(theGraphLending.paymentToken),
      lentAt: Number(theGraphLending.lentAt),
    };
  };

  return theGraphLendings.map(theGraphToLending);
};
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.renft.io/developers/sdk/renft-sdk-v6.0.0/collateral-free-integration-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
