juna
v3.12.4
Published
A cross platform NFT lending client for serious lenders
Downloads
127
Maintainers
Readme
JUNA - A cross platform NFT lending client for serious lenders
Setup
For users (not implemented)
npm install juna
For contributors
Clone the repository
git clone https://github.com/swissquant/juna.git
Install bun:
curl -fsSL https://bun.sh/install | bash
Install dependencies:
bun install
You're good to go!
Usage
Client initialization
Platform specific client
To only operate from a specific lending platform.
Please note that privateKey is optional. It is only necessary if you want to create loan offers.
import { NftfiClient, ArcadeClient, GondiClient } from "juna";
// Arcade client
const arcadeClient = new ArcadeClient({ privateKey: PRIVATE_KEY, apiKey: API_KEY });
// Nftfi client
const nftfiClient = new NftfiClient({ privateKey: PRIVATE_KEY, apiKey: API_KEY });
// Gondi client
const gondiClient = new GondiClient({ privateKey: PRIVATE_KEY });
Portfolio client
If you aim to operate seamlessly across various lending platforms simultaneously.
Please note:
- Addresses should be specified in case you want to retrieve your loan portfolio across different wallets
- Clients should be initialised with private keys in case you want to publish loan offers
import { PortfolioClient } from "juna";
const portfolioClient = new PortfolioClient([nftfiClient, arcadeClient, gondiClient], [ADDRESS1, ADDRESS2]);
Creating an offer
Collection offer
import { WETH, DAI, USDC } from "juna";
// Works identically for both platform specific and portfolio clients
const offer = await client.createCollectionOffer({
collectionAddress: "0xed5af388653567af2f388e6224dc7c4b3241c544", // azuki
currency: WETH,
principal: 0.1, // 0.1 weth
apr: 0.15, // 15%
durationInDays: 30, // 30 days
expiryInMinutes: 5, // offer expires in 5 minutes
});
Single item offer (not implemented)
import { WETH, DAI, USDC } from "juna";
// Works identically for both platform specific and portfolio clients
const offer = await client.createSingleItemOffer({
collectionAddress: "0xed5af388653567af2f388e6224dc7c4b3241c544", // azuki
nftId: 10, // offering only to the nft id 10
currency: WETH,
principal: 0.1, // 0.1 weth
apr: 0.15, // 15%
durationInDays: 30, // 30 days
expiryInMinutes: 5, // offer expires in 5 minutes
});
Getting loans
Format
export interface Loan {
id: string;
platform: LendingPlatform;
borrower: `0x${string}`;
lender: `0x${string}`;
status: LoanStatus;
startDate: Date;
endDate: Date;
currency: Currency;
principal: number;
durationInDays: number;
apr: number;
collateral: Collateral[];
}
export interface Collateral {
collectionAddress: `0x${string}`;
collectionName: string;
nftId: number;
}
All historical loans (not implemented)
const loans = await client.getLoans();
By account
For platform specific client
const loans = await client.getLoansForAccount(ACCOUNT_ADDRESS);
For portfolio client (addresses are specified at client initalisation)
const loans = await client.getMyLoans();
By collection (not implemented)
const loans = await client.getLoansForCollection(COLLECTION_ADDRESS);
Getting offers
Format
interface Offer {
id: string;
platform: LendingPlatform;
lender: `0x${string}`;
offerDate: Date;
expiryDate: Date;
type: OfferType;
currency: Currency;
principal: number;
durationInDays: number;
apr: number;
collateral: {
collectionAddress: `0x${string}`;
collectionName: string;
nftId: string;
};
}
export enum OfferType {
collectionOffer = "collectionOffer",
singleItemOffer = "singleItemOffer",
}
All offers (not implemented)
const offers = await client.getOffers();
By account (not implemented)
For platform specific clients
const offers = await client.getOffersForAccount(ACCOUNT_ADDRESS);
For portfolio client (addresses are specified at client initalisation)
const loans = await client.getMyOffers();
By collection (not implemented)
const offers = await client.getOffersForCollection(COLLECTION_ADDRESS);
Tests
bun test
Architecture
- The different clients all implement the interface
LendingClient
and use the common types insrc/types.ts
to offer a uniform API. - Since the number of currency tokens is limited we export them as pre-defined const objects
from
src/support/currencies.ts
. - Each client has an API it interacts with; it uses specific types (e.g.
src/arcade/support/types.ts
) and uses mappers to transform them in the common types mentioned above. - This library relies on Viem to handle Ethereum logic and Bun as runtime; however we don't explicitly use Bun global except for testing so that this can also be run from Node.