LogoLogo
HomeLaunch App
  • Introduction
  • General Info
    • Rental Use Cases
    • Compatible Blockchains
    • Whitelabel Interface
    • Custom Solutions
    • Protocol Composability
    • Protocol Fee
    • Frequently Asked (FAQ)
  • Rental Solutions
    • Collateral-Free
    • Collateralized
  • Developers
    • Integration Guide
    • SDK
      • @renft/sdk@^v6.0.0
        • Interacting with Smart Contracts
        • Collateral-Free Integration Guide
        • Castle Crush (Reward Share)
      • @renft/sdk@v5.0.4
        • Collateral-Free Integration Guide
        • Castle Crush (Reward Share)
    • reNFT Contracts' Addresses
    • Querying reNFT's on-chain data
      • Castle Crush (Reward Share)
  • Video Tutorials
    • Collateral-Free
      • How To Lend
      • How To Rent
    • Castle Crush (Reward Share)
      • How To Lend
      • How To Rent
    • Collateralized
      • How To Lend
      • How To Rent
      • Returning & Defaulting
    • Expired Rentals
  • About reNFT
    • Team
    • Contact
Powered by GitBook
On this page
  • Lending and Renting NFTs​
  • Batching​ Transactions
  • Lending
  • Rent​ing
  • Stopping a Rental
  • Claiming Rent​
  • Stopping a Lending​
  • How to unpack data?​
  1. Developers
  2. SDK
  3. @renft/sdk@^v6.0.0

Collateral-Free Integration Guide

The official instructions on how to interact with our open Collateral-Free rental contracts.

PreviousInteracting with Smart ContractsNextCastle Crush (Reward Share)

Last updated 2 years ago

This tutorial was written for SDK version 6.0.0.

Lending and Renting NFTs

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

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,
});
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

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:

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]
);

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.

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

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.

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],
);

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!

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],
);

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.

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],
);

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:

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);
};

To interact with our smart contracts, we always recommend using our . 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.

💭 We name our contracts after famous cats! You can find the name mappings . Meow!

Batching Transactions

Any of the following functions support batching. This is shown below for the lend() instruction, where the user lends an and a within the same function call:

Renting

💭 Invocations to stopLend() are disabled until the lender calls claimRent() first.

Claiming Rent

Stopping a Lending

To learn about more about how we determine the status of a particular lending or renting, check out !

How to unpack data?

SDK
here
​
AstroCat
CatPlsr
​
​
​
​
this guide
​
​
reNFT collateral-free contract flows