> For the complete documentation index, see [llms.txt](https://docs.renft.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.renft.io/developers/sdk/renft-sdk-v5.0.4/castle-crush-reward-share.md).

# Castle Crush (Reward Share)

reNFT's SDK is written in Typescript, but we plan to add more languages in the future (Python and Golang, at the very least). You can install the SDK by running `yarn add @renft/sdk`.

## Lend

Wildlife contract takes custody of the Castle Crush NFT. However, the NFT does not get transferred on rent. It sits inside of the Wildlife contract for as long as the lending is active. If there is no active renting, the lender may choose to terminate the lending. However, if there is an active renting, the lender must wait for it to conclude.

Because Wildlife contract takes custody of the NFT, you will need to approve the NFT you wish to lend to be operated by the contract. You can find an example of how to do it [here](https://github.com/re-nft/sdk/blob/8c61b61be8c649774df332a3078b4d1267f23ad6/examples/whoopi.js#L44). Once you have done that, you can lend NFT(s)

```typescript
import { JsonRpcProvider } from '@ethersproject/providers';
import { parseFixed } from '@ethersproject/bignumber';
import { Wallet } from '@ethersproject/wallet';
import { Whoopi, PaymentToken, RESOLVERS, RenftContracts } from '@renft/sdk';

const provider = new JsonRpcProvider('https://api.avax-test.network/ext/bc/C/rpc');
const privKey = '';
let wallet = new Wallet(privKey);
wallet = wallet.connect(provider);

let txn;
let receipt;

const castleCrushNftAddress = "0xeA4E79F0a40A9A468a5159499b738dc6b1332447";
const whoopiAddress = "0x516775e81b0d1fC91Ec326DEd21c33728895Fc6C";
const whoopi = new Whoopi(wallet, whoopiAddress);

const tokenId = [210, 200];
// ! Note that if allowedRenters is empty, you must set upfrontRentFee to
// ! a non zero value.
const upfrontRentFee = [
  parseFixed("1", RESOLVERS[RenftContracts.WHOOPI_FUJI][PaymentToken.USDC]).toString(),
  parseFixed("1", RESOLVERS[RenftContracts.WHOOPI_FUJI][PaymentToken.USDC]).toString()
];
// ! you can't use SENTINEL as a payment token, even though
// ! you don't want to set an upfront rent fee. Just use any
// ! payment token in such a case.
const paymentToken = [PaymentToken.USDC, PaymentToken.USDC];
const revShareBeneficiaries = [
  ["0x000000045232fe75A3C7db3e5B03B0Ab6166F425", "0x465DCa9995D6c2a81A9Be80fBCeD5a770dEE3daE"],
  ["0x465DCa9995D6c2a81A9Be80fBCeD5a770dEE3daE", "0xeA4E79F0a40A9A468a5159499b738dc6b1332447"]
];
// ! portions sum cannot be 100 here. At lend, we don't know who will rent,
// ! and the renter is always a mandatory part in rev share. We are not setting
// ! the renter here at lend time. Therefore, 100 - sum(portions) is what
// ! gets eventually assigned to the renter.
const revSharePortions = [
  [50, 40], // 10% is how much the renter will get on this lending
  [90, 5] // 5% is how much ther renter will get on this lending
];
// * means 1 and 2 cycles respectively
const maxRentDuration = [1, 2];

txn = await whoopi.lend(
  castleCrushNftAddress,
  tokenId,
  upfrontRentFee,
  revShareBeneficiaries,
  revSharePortions,
  maxRentDuration,
  paymentToken,
  undefined,
  // ! uncomment this if it does not allow you to execute because it predicts that
  // ! the transaction will fail
  // { gasLimit: 1000000 }
);
receipt = await txn.wait();
```

## Rent

To rent, you must approve the payment token of the lending to be operated by the Wildlife contract. To do so, see an example [here](https://github.com/re-nft/sdk/blob/8c61b61be8c649774df332a3078b4d1267f23ad6/examples/whoopi.js#L90). Once you have done that for the amount of `upfrontRentFee` or more, you can proceed with the renting

```typescript
const tokenId = [210, 200];
const lendingId = [3, 4];
const rentingDuration = [1, 2];

txn = await whoopi.rent(
  castleCrushNftAddress,
  tokenId,
  lendingId,
  rentingDuration
  // { gasLimit: 1000000 }
);
receipt = await txn.wait();
```

## Stop Lending

A lender can only stop the lending if there is no active renting associated with the lending. This is why it is important to set a `maxRentDuration` to the maximum number of cycles that the lender is happy with. For example, if `maxRentDuration` is set to `3` it would mean that someone can come in and rent the lending for up to `3` consecutive cycles. You do not need to approve anything from the lender's side on this step, so you are free to call the stop lending function.

```typescript
const tokenId = [210, 200];
const lendingId = [3, 4];

txn = await whoopi.stopLending(
  castleCrushNftAddress,
  tokenId,
  lendingId,
  // { gasLimit: 1000000 }
)
receipt = await txn.wait();
```

## Stop Renting

This is handled by reNFT's bot and there is no need to worry about renter's doing this themselves. In fact, only reNFT's bot is able to stop the rentals. It does so at midnight after cycle-end. The bot checks all of the rentings every hour. That means that it is possible that it will stop the renting with up to but not exceeding one hour delay. Due to the indexing solution requiring payments for every query made, one hour is a good value to stick to.

## Pay Rewards

As with renting, you must ensure that the Wildlife contract is approved to operate your ERC20 reward token. Follow the link in the Rent section to see an example on how to do this. Once approved, you are able to simply send a lump sum per lending (along with the renters' addresses), the contract will then handle the reward splitting as per the conditions of the original lending (i.e. taking into account other revenue share parties and their respective shares on this particular lending)

```typescript
const tokenId = [210, 200];
const lendingId = [3, 4];
const renterAddress = ["0x465DCa9995D6c2a81A9Be80fBCeD5a770dEE3daE", "0x465DCa9995D6c2a81A9Be80fBCeD5a770dEE3daE"];
const amountToPay = [
  parseFixed("1", RESOLVERS[RenftContracts.WHOOPI_FUJI][PaymentToken.USDC]).toString(),
  parseFixed("1", RESOLVERS[RenftContracts.WHOOPI_FUJI][PaymentToken.USDC]).toString()
];

txn = await whoopi.pay(
  castleCrushNftAddress,
  tokenId,
  lendingId,
  renterAddress,
  amountToPay,
  // { gasLimit: 1000000 }
);
receipt = await txn.wait();
```

## Query On-chain data

To learn about how to query the on-chain data, read [here](/developers/querying-renfts-on-chain-data/castle-crush-reward-share.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.renft.io/developers/sdk/renft-sdk-v5.0.4/castle-crush-reward-share.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
