@rainfi/sdk
Version:
This package is used to interact with Rain.fi protocol on Solana
911 lines • 126 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRuleset = exports.repayCompressedLoan = exports.borrowCompressed = exports.claimSale = exports.delistNft = exports.listNft = exports.sellNft = exports.unfreeze = exports.executeMortgageRequest = exports.acceptMortgageRequest = exports.poolCancelMortgageProposal = exports.cancelMortgageRequest = exports.makeMortgageRequest = exports.liquidate = exports.buyLoanMortgage = exports.sellLoanMortgage = exports.freeze = exports.buyMortgage = exports.configMortgage = exports.executeLoanRequest = exports.acceptLoanRequest = exports.poolCancelLoanProposal = exports.cancelLoanRequest = exports.makeLoanRequest = exports.setMaxAmountUsable = exports.updatePoolWhitelist = exports.closePool = exports.updatePoolStatus = exports.withdrawLiquidity = exports.addLiquidity = exports.repayLoan = exports.extendLoan = exports.borrow = exports.updatePoolCollections = exports.updatePool = exports.createPool = void 0;
const web3_js_1 = require("@solana/web3.js");
const tools_utils_1 = require("./tools.utils");
const pda_utils_1 = require("./pda.utils");
const generated_1 = require("../generated");
const fetch_utils_1 = require("./fetch.utils");
const constant_1 = require("./constant");
const instructions = __importStar(require("../generated/instructions"));
const metadata_utils_1 = require("./metadata.utils");
const bn_js_1 = __importDefault(require("bn.js"));
const solanart_1 = require("./marketplaces/solanart");
const spl_token_1 = require("@solana/spl-token");
// import { Request } from '../generated/accounts/Request';
const mpl_token_metadata_1 = require("@metaplex-foundation/mpl-token-metadata");
const LoanKind_1 = require("../generated/types/LoanKind");
const Request_1 = require("../generated/accounts/Request");
const axios_1 = __importDefault(require("axios"));
const anchor_1 = require("@coral-xyz/anchor");
const idl_1 = require("../utils/marketplaces/magic_eden/idl");
const layout_utils_1 = require("./layout.utils");
const spl_account_compression_1 = require("@solana/spl-account-compression");
// import { computeCompressedNFTHash, computeCreatorHash, computeDataHash } from "@metaplex-foundation/mpl-bubblegum";
function createPool(connection, publicKey, args, splAddress) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const signerTa = (0, tools_utils_1.getAtaForMint)(splAddress, publicKey);
const currencyInfo = yield (0, tools_utils_1.getCurrency)(splAddress.toBase58());
const ixs = [
instructions.createCreatePoolInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
pool: (0, pda_utils_1.findPoolPda)(publicKey),
authority: (0, pda_utils_1.findAuthorityPda)(publicKey),
signerTa,
vault: (0, pda_utils_1.findPoolVaultPda)(publicKey),
currency: splAddress,
pythPoolFeed: new web3_js_1.PublicKey((_b = (_a = currencyInfo.priceAccountV2) !== null && _a !== void 0 ? _a : currencyInfo.switchBoardOnDemandAccount) !== null && _b !== void 0 ? _b : currencyInfo.switchBoardAccount),
pythSolFeed: constant_1.PYTH_SOL_ORACLE_PUBKEY,
referrer: args.referrer ? new web3_js_1.PublicKey(args.referrer) : constant_1.RAIN_PROGRAM,
}, {
isCompounded: args.compound,
curve: {
baseInterest: args.baseInterest,
interestRate: args.interestRate,
curveRate: args.curveRate,
curveRateDay: args.curveRateDay,
maxDuration: args.maxDuration * 3600 * 24,
maxAmount: args.maxAmount,
},
amount: args.amount,
collections: args.collections,
}),
];
if (spl_token_1.NATIVE_MINT.equals(splAddress)) {
ixs.unshift(...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa, args.amount)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
return ixs;
});
}
exports.createPool = createPool;
function updatePool(publicKey, args) {
return __awaiter(this, void 0, void 0, function* () {
return instructions.createUpdatePoolInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
pool: (0, pda_utils_1.findPoolPda)(publicKey),
referrer: args.referrer ? new web3_js_1.PublicKey(args.referrer) : constant_1.RAIN_PROGRAM,
}, args);
});
}
exports.updatePool = updatePool;
function updatePoolCollections(publicKey, collections) {
return __awaiter(this, void 0, void 0, function* () {
return instructions.createUpdatePoolCollectionsInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
pool: (0, pda_utils_1.findPoolPda)(publicKey),
referrer: constant_1.RAIN_PROGRAM,
}, { collections });
});
}
exports.updatePoolCollections = updatePoolCollections;
function borrow(connection_1, publicKey_1, args_1) {
return __awaiter(this, arguments, void 0, function* (connection, publicKey, args, referrer = undefined) {
var _a, _b, _c;
const loan = new web3_js_1.Keypair();
const poolOwner = new web3_js_1.PublicKey(args.poolOwner);
const collectionId = yield (0, tools_utils_1.getGlobalOfferIdFromMint)(connection, args.nftMint);
const pool = yield (0, fetch_utils_1.fetchPoolFromOwner)(connection, poolOwner);
const currencyInfo = yield (0, tools_utils_1.getCurrency)((_a = pool.currency) === null || _a === void 0 ? void 0 : _a.toString());
const referrerTa = referrer ? (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), referrer) : constant_1.RAIN_PROGRAM;
const nftAta = (0, tools_utils_1.getAtaForMint)(args.nftMint, publicKey);
const signerTa = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), publicKey);
const authority = (0, pda_utils_1.findAuthorityPda)(poolOwner);
const metadataAddress = (0, tools_utils_1.getMetadataAddress)(args.nftMint);
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const { ruleSet, isPnft } = getRuleset(metadata);
var whitelistIndex = 0;
if (args.lookupTable) {
const lookupTableAccount = yield connection.getAddressLookupTable(args.lookupTable);
if (lookupTableAccount === null || lookupTableAccount === void 0 ? void 0 : lookupTableAccount.value) {
whitelistIndex = lookupTableAccount && (lookupTableAccount === null || lookupTableAccount === void 0 ? void 0 : lookupTableAccount.value.state.addresses.findIndex(x => x.equals(publicKey)));
}
else {
console.log("Unable to fetch lookup table");
}
}
// const ltv = pool.collections.find(x => x.collection == collectionId)?.collectionLtv || 0
const vaultTokenAccount = (0, tools_utils_1.getAtaForMint)(args.nftMint, authority);
const additionalComputeBudgetInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
units: 1400000,
});
const ixs = [
instructions.createTakeLoanInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
signerTa,
nftTa: nftAta,
nftMint: args.nftMint,
nftMetadata: (0, tools_utils_1.getMetadataAddress)(args.nftMint),
nftEdition: (0, pda_utils_1.getNFTEdition)(args.nftMint),
loan: loan.publicKey,
vaultTokenAccount,
collection: (0, pda_utils_1.findCollectionPda)(collectionId),
pool: (0, pda_utils_1.findPoolPda)(poolOwner),
poolCurrency: new web3_js_1.PublicKey(pool.currency),
authority,
poolOwner,
whitelist: (0, pda_utils_1.getWhitelistPda)(args.nftMint),
pythPoolFeed: new web3_js_1.PublicKey((_c = (_b = currencyInfo.priceAccountV2) !== null && _b !== void 0 ? _b : currencyInfo.switchBoardOnDemandAccount) !== null && _c !== void 0 ? _c : currencyInfo.switchBoardAccount),
pythSolFeed: constant_1.PYTH_SOL_ORACLE_PUBKEY,
rainTa: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), constant_1.RAIN_FEES_ADDRESS),
instructions: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
authorizationRulesProgram: constant_1.AUTH_PROGRAM_ID,
metadataProgram: constant_1.METADATA_PROGRAM_ID,
vault: (0, pda_utils_1.findPoolVaultPda)(poolOwner),
associatedTokenProgram: constant_1.ASSOCIATED_TOKEN_PROGRAM_ID,
referrerTa,
lookupTable: args.lookupTable ? args.lookupTable : constant_1.RAIN_PROGRAM,
}, {
collectionId: collectionId,
duration: args.duration * 3600 * 24,
interest: args.interest,
amountInLamports: args.amount,
slippage: args.slippage,
whitelistIndex,
}),
];
isPnft &&
(ixs === null || ixs === void 0 ? void 0 : ixs[0].keys.push(...[
{
isSigner: false,
isWritable: true,
pubkey: (0, pda_utils_1.findTokenRecordPDA)(args.nftMint, nftAta),
},
{
isSigner: false,
isWritable: true,
pubkey: (0, pda_utils_1.findTokenRecordPDA)(args.nftMint, vaultTokenAccount),
},
{
isSigner: false,
isWritable: false,
pubkey: ruleSet,
},
]));
if (spl_token_1.NATIVE_MINT.equals(new web3_js_1.PublicKey(pool.currency))) {
ixs.unshift(additionalComputeBudgetInstruction, ...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
else {
const addAta = yield (0, tools_utils_1.initAtaIfNeeded)(connection, publicKey, signerTa, new web3_js_1.PublicKey(pool.currency));
addAta && ixs.unshift(addAta);
ixs.unshift(additionalComputeBudgetInstruction);
}
const initReferrer = referrer ? (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(publicKey, referrerTa, new web3_js_1.PublicKey(referrer), new web3_js_1.PublicKey(pool === null || pool === void 0 ? void 0 : pool.currency)) : null;
if (initReferrer) {
ixs.unshift(initReferrer);
}
return {
instruction: ixs,
signers: loan,
};
});
}
exports.borrow = borrow;
function extendLoan(connection_1, publicKey_1, args_1, amount_1) {
return __awaiter(this, arguments, void 0, function* (connection, publicKey, args, amount, referrer = undefined) {
var _a, _b, _c;
const newLoan = new web3_js_1.Keypair();
const poolOwner = new web3_js_1.PublicKey(args.poolOwner);
const collectionId = yield (0, tools_utils_1.getGlobalOfferIdFromMint)(connection, args.nftMint);
const pool = yield (0, fetch_utils_1.fetchPoolFromOwner)(connection, poolOwner);
const nftAta = (0, tools_utils_1.getAtaForMint)(args.nftMint, publicKey);
const signerTa = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), publicKey);
const authority = (0, pda_utils_1.findAuthorityPda)(poolOwner);
const currencyInfo = yield (0, tools_utils_1.getCurrency)((_a = pool.currency) === null || _a === void 0 ? void 0 : _a.toString());
const referrerTa = referrer ? (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), referrer) : constant_1.RAIN_PROGRAM;
var whitelistIndex = 0;
if (args.lookupTable) {
const lookupTableAccount = yield connection.getAddressLookupTable(args.lookupTable);
if (lookupTableAccount === null || lookupTableAccount === void 0 ? void 0 : lookupTableAccount.value) {
whitelistIndex = lookupTableAccount && (lookupTableAccount === null || lookupTableAccount === void 0 ? void 0 : lookupTableAccount.value.state.addresses.findIndex(x => x.equals(publicKey)));
}
else {
console.log("Unable to fetch lookup table");
}
}
const vaultTokenAccount = (0, tools_utils_1.getAtaForMint)(args.nftMint, authority);
const additionalComputeBudgetInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
units: 1400000,
});
const ixs = [
instructions.createExtendLoanInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
signerTa,
nftAta,
nftMint: args.nftMint,
nftMetadata: (0, tools_utils_1.getMetadataAddress)(args.nftMint),
loan: args.loan,
newLoan: newLoan.publicKey,
vaultTokenAccount,
collection: (0, pda_utils_1.findCollectionPda)(collectionId),
pool: (0, pda_utils_1.findPoolPda)(poolOwner),
poolCurrency: new web3_js_1.PublicKey(pool.currency),
poolOwnerAta: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), poolOwner),
authority,
poolOwner,
whitelist: (0, pda_utils_1.getWhitelistPda)(args.nftMint),
pythPoolFeed: new web3_js_1.PublicKey((_c = (_b = currencyInfo.priceAccountV2) !== null && _b !== void 0 ? _b : currencyInfo.switchBoardOnDemandAccount) !== null && _c !== void 0 ? _c : currencyInfo.switchBoardAccount),
pythSolFeed: constant_1.PYTH_SOL_ORACLE_PUBKEY,
rainTa: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), constant_1.RAIN_FEES_ADDRESS),
instructions: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
authorizationRulesProgram: constant_1.AUTH_PROGRAM_ID,
metadataProgram: constant_1.METADATA_PROGRAM_ID,
vault: (0, pda_utils_1.findPoolVaultPda)(poolOwner),
associatedTokenProgram: constant_1.ASSOCIATED_TOKEN_PROGRAM_ID,
lookupTable: args.lookupTable ? args.lookupTable : constant_1.RAIN_PROGRAM,
referrerTa,
}, {
collectionId: collectionId,
duration: args.duration * 3600 * 24,
interest: args.interest,
amountInLamports: args.amount,
slippage: args.slippage,
whitelistIndex
}),
];
if (spl_token_1.NATIVE_MINT.equals(new web3_js_1.PublicKey(pool.currency))) {
ixs.unshift(additionalComputeBudgetInstruction, ...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa, amount)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
else {
ixs.unshift(additionalComputeBudgetInstruction);
}
const initAta = yield (0, tools_utils_1.initAtaIfNeeded)(connection, publicKey, nftAta, args.nftMint);
initAta && ixs.unshift(initAta);
return {
instruction: ixs,
signers: newLoan,
};
});
}
exports.extendLoan = extendLoan;
function repayLoan(connection, publicKey, address, amount) {
return __awaiter(this, void 0, void 0, function* () {
const loan = address;
const loanAccount = yield generated_1.Loan.fromAccountAddress(connection, loan);
const nftMint = loanAccount.mint;
const poolOwner = loanAccount.lender;
const signerTa = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(loanAccount.currency), publicKey);
const metadataAddress = (0, tools_utils_1.getMetadataAddress)(nftMint);
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const { ruleSet, isPnft } = getRuleset(metadata);
const additionalComputeBudgetInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
units: 1400000,
});
const authority = (0, pda_utils_1.findAuthorityPda)(poolOwner);
// var vaultTokenAccount
// if (parseEnum(loanAccount.kind) == "loan") {
// vaultTokenAccount = findLoanVaultTokenAccount(address)
// } else {
// vaultTokenAccount = getAtaForMint(new PublicKey(loanAccount.mint), authority)
// }
const vaultTokenAccount = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(loanAccount.mint), authority);
const nftAta = (0, tools_utils_1.getAtaForMint)(nftMint, publicKey);
const ixs = [
instructions.createRepayInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
signerTa,
nftAta,
nftMint,
nftMetadata: (0, tools_utils_1.getMetadataAddress)(nftMint),
nftEdition: (0, pda_utils_1.getNFTEdition)(nftMint),
loan,
vaultTokenAccount,
collection: (0, pda_utils_1.findCollectionPda)(loanAccount.collection),
pool: (0, pda_utils_1.findPoolPda)(poolOwner),
authority: authority,
poolOwner,
vault: (0, pda_utils_1.findPoolVaultPda)(poolOwner),
poolOwnerAta: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(loanAccount.currency), poolOwner),
poolMint: new web3_js_1.PublicKey(loanAccount.currency),
rainTa: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(loanAccount.currency), constant_1.RAIN_FEES_ADDRESS),
metadataProgram: constant_1.METADATA_PROGRAM_ID,
associatedTokenProgram: constant_1.SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
instructions: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
authorizationRulesProgram: constant_1.AUTH_PROGRAM_ID,
}, {
collectionId: loanAccount.collection,
}),
];
isPnft &&
(ixs === null || ixs === void 0 ? void 0 : ixs[0].keys.push(...[
{
isSigner: false,
isWritable: true,
pubkey: (0, pda_utils_1.findTokenRecordPDA)(nftMint, nftAta),
},
{
isSigner: false,
isWritable: true,
pubkey: (0, pda_utils_1.findTokenRecordPDA)(nftMint, vaultTokenAccount),
},
{
isSigner: false,
isWritable: false,
pubkey: ruleSet,
},
]));
if (spl_token_1.NATIVE_MINT.equals(new web3_js_1.PublicKey(loanAccount.currency))) {
ixs.unshift(additionalComputeBudgetInstruction, ...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa, amount)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
else {
ixs.unshift(additionalComputeBudgetInstruction);
}
const initAta = yield (0, tools_utils_1.initAtaIfNeeded)(connection, publicKey, nftAta, nftMint);
initAta && ixs.unshift(initAta);
return ixs;
});
}
exports.repayLoan = repayLoan;
// export async function liquidateLoan(
// connection: Connection,
// publicKey: PublicKey,
// address: PublicKey,
// ): Promise<TransactionInstruction> {
// const loan = address
// const loanAccount = await Loan.fromAccountAddress(connection, loan)
// const nftMint = loanAccount.mint
// const poolOwner = loanAccount.lender
// const tokenManager = (await findTokenManagerAddress(nftMint))?.[0];
// const mintCounter = (await findMintCounterId(nftMint))?.[0];
// return instructions.createLiquidateInstruction(
// {
// signer: publicKey,
// signerTa: getAtaForMint(nftMint, publicKey),
// nftMint,
// nftMetadata: getMetadataAddress(nftMint),
// nftEdition: getNFTEdition(nftMint),
// collection: findCollectionPda(loanAccount.collection as number),
// borrower: loanAccount.borrower,
// borrowerStats: findSignerStatsPda(loanAccount.borrower),
// borrowerNftAta: getAtaForMint(nftMint, loanAccount.borrower),
// loan,
// loanVault: getSplMortgageVaultPda(loan),
// pool: findPoolPda(poolOwner),
// authority: findAuthorityPda(poolOwner),
// tokenManager,
// tokenManagerTokenAccount: findTokenManagerPda(nftMint),
// mintCounter,
// cardinalProgram: TOKEN_MANAGER_ADDRESS,
// metadataProgram: METADATA_PROGRAM_ID,
// associatedTokenProgram: SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
// instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
// authorizationRulesProgram: AUTH_PROGRAM_ID,
// },
// {
// collectionId: loanAccount.collection
// }
// )
// }
function addLiquidity(connection, publicKey, amount) {
return __awaiter(this, void 0, void 0, function* () {
const pool = yield (0, fetch_utils_1.fetchPoolFromOwner)(connection, publicKey);
const signerTa = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), publicKey);
const ixs = [
instructions.createAddLiquidityInstruction({
signer: publicKey,
signerTa: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), publicKey),
pool: (0, pda_utils_1.findPoolPda)(publicKey),
authority: (0, pda_utils_1.findAuthorityPda)(publicKey),
vault: (0, pda_utils_1.findPoolVaultPda)(publicKey),
}, {
amount: amount,
}),
];
if (spl_token_1.NATIVE_MINT.equals(new web3_js_1.PublicKey(pool.currency))) {
ixs.unshift(...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa, amount)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
return ixs;
});
}
exports.addLiquidity = addLiquidity;
function withdrawLiquidity(connection, publicKey, amount) {
return __awaiter(this, void 0, void 0, function* () {
const pool = yield (0, fetch_utils_1.fetchPoolFromOwner)(connection, publicKey);
const signerTa = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), publicKey);
const ixs = [
instructions.createWithdrawLiquidityInstruction({
signer: publicKey,
signerTa,
pool: (0, pda_utils_1.findPoolPda)(publicKey),
authority: (0, pda_utils_1.findAuthorityPda)(publicKey),
vault: (0, pda_utils_1.findPoolVaultPda)(publicKey),
}, {
amount: amount,
}),
];
if (spl_token_1.NATIVE_MINT.equals(new web3_js_1.PublicKey(pool.currency))) {
ixs.unshift(...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
return ixs;
});
}
exports.withdrawLiquidity = withdrawLiquidity;
function updatePoolStatus(publicKey, status) {
return instructions.createUpdatePoolStatusInstruction({
signer: publicKey,
pool: (0, pda_utils_1.findPoolPda)(publicKey),
}, { status });
}
exports.updatePoolStatus = updatePoolStatus;
function closePool(publicKey) {
return instructions.createClosePoolInstruction({
signer: publicKey,
pool: (0, pda_utils_1.findPoolPda)(publicKey),
authority: (0, pda_utils_1.findAuthorityPda)(publicKey),
vault: (0, pda_utils_1.findPoolVaultPda)(publicKey),
});
}
exports.closePool = closePool;
function updatePoolWhitelist(publicKey, lookupTable) {
return instructions.createUpdatePoolWhitelistInstruction({
signer: publicKey,
pool: (0, pda_utils_1.findPoolPda)(publicKey),
lookupTable: lookupTable ? lookupTable : constant_1.RAIN_PROGRAM
});
}
exports.updatePoolWhitelist = updatePoolWhitelist;
function setMaxAmountUsable(publicKey, amount) {
return instructions.createUpdateUsableAmountInstruction({
signer: publicKey,
pool: (0, pda_utils_1.findPoolPda)(publicKey),
}, {
usableAmount: amount,
});
}
exports.setMaxAmountUsable = setMaxAmountUsable;
function makeLoanRequest(connection, publicKey, args) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
//on Hold
const collectionId = (_a = args.collectionId) !== null && _a !== void 0 ? _a : yield (0, tools_utils_1.getGlobalOfferIdFromMint)(connection, args.nftMint);
return instructions.createProposeLoanInstruction({
signer: publicKey,
nftMint: args.nftMint,
nftMetadata: (0, tools_utils_1.getMetadataAddress)(args.nftMint),
collection: (0, pda_utils_1.findCollectionPda)(collectionId),
pool: (0, pda_utils_1.findPoolPda)(args.poolOwner),
request: (0, pda_utils_1.findRequestPda)(publicKey, args.nftMint),
whitelist: (0, pda_utils_1.getWhitelistPda)(args.nftMint),
}, {
collectionId,
kind: LoanKind_1.LoanKind.Loan,
amount: args.amount,
duration: args.duration * 3600 * 24,
price: 0,
marketplace: generated_1.Marketplace.None,
});
});
}
exports.makeLoanRequest = makeLoanRequest;
function cancelLoanRequest(connection, publicKey, loanRequestAddress) {
return __awaiter(this, void 0, void 0, function* () {
const loanRequestAccount = yield Request_1.Request.fromAccountAddress(connection, loanRequestAddress);
return instructions.createCancelProposalInstruction({
signer: publicKey,
nftMint: loanRequestAccount.mint,
request: (0, pda_utils_1.findRequestPda)(publicKey, loanRequestAccount.mint),
});
});
}
exports.cancelLoanRequest = cancelLoanRequest;
function poolCancelLoanProposal(connection, publicKey, loanRequestAddress) {
return __awaiter(this, void 0, void 0, function* () {
const loanRequestAccount = yield Request_1.Request.fromAccountAddress(connection, loanRequestAddress);
return instructions.createPoolCancelProposalInstruction({
borrower: loanRequestAccount.borrower,
pool: loanRequestAccount.pool,
signer: publicKey,
nftMint: loanRequestAccount.mint,
request: loanRequestAddress,
});
});
}
exports.poolCancelLoanProposal = poolCancelLoanProposal;
function acceptLoanRequest(connection, publicKey, loanRequestAddress) {
return __awaiter(this, void 0, void 0, function* () {
const loanRequestAccount = yield Request_1.Request.fromAccountAddress(connection, loanRequestAddress);
const collectionId = loanRequestAccount.collection;
return instructions.createAcceptProposalInstruction({
signer: publicKey,
nftMint: loanRequestAccount.mint,
pool: loanRequestAccount.pool,
request: loanRequestAddress,
borrower: loanRequestAccount.borrower,
}, {
collectionId,
kind: LoanKind_1.LoanKind.Loan,
amount: loanRequestAccount.amount,
duration: loanRequestAccount.duration,
price: 0,
marketplace: generated_1.Marketplace.None,
});
});
}
exports.acceptLoanRequest = acceptLoanRequest;
function executeLoanRequest(connection, publicKey, args) {
return __awaiter(this, void 0, void 0, function* () {
const loan = new web3_js_1.Keypair();
const loanRequestAccount = yield Request_1.Request.fromAccountAddress(connection, args.loanRequestAddress);
const collectionId = loanRequestAccount.collection;
const pool = yield (0, fetch_utils_1.parsePoolAccount)((yield generated_1.Pool.fromAccountAddress(connection, loanRequestAccount.pool)).pretty());
const poolOwner = new web3_js_1.PublicKey(pool.owner);
const nftAta = (0, tools_utils_1.getAtaForMint)(loanRequestAccount.mint, publicKey);
const signerTa = (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), publicKey);
const authority = (0, pda_utils_1.findAuthorityPda)(poolOwner);
const metadataAddress = (0, tools_utils_1.getMetadataAddress)(loanRequestAccount === null || loanRequestAccount === void 0 ? void 0 : loanRequestAccount.mint);
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const { ruleSet, isPnft } = getRuleset(metadata);
const vaultTokenAccount = (0, tools_utils_1.getAtaForMint)(loanRequestAccount.mint, authority);
var whitelistIndex = 0;
if (args.lookupTable) {
const lookupTableAccount = yield connection.getAddressLookupTable(args.lookupTable);
if (lookupTableAccount === null || lookupTableAccount === void 0 ? void 0 : lookupTableAccount.value) {
whitelistIndex = lookupTableAccount && (lookupTableAccount === null || lookupTableAccount === void 0 ? void 0 : lookupTableAccount.value.state.addresses.findIndex(x => x.equals(publicKey)));
}
else {
console.log("Unable to fetch lookup table");
}
}
const additionalComputeBudgetInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
units: 400000,
});
const ixs = [
instructions.createExecuteLoanInstruction({
signer: publicKey, //borrower
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
signerTa,
nftTa: nftAta,
nftMint: loanRequestAccount.mint,
nftEdition: (0, pda_utils_1.getNFTEdition)(loanRequestAccount.mint),
nftMetadata: metadataAddress,
loan: loan.publicKey,
vaultTokenAccount,
collection: (0, pda_utils_1.findCollectionPda)(collectionId),
pool: (0, pda_utils_1.findPoolPda)(poolOwner),
pythPoolFeed: new web3_js_1.PublicKey(pool.oraclePoolUsd),
poolCurrency: new web3_js_1.PublicKey(pool.currency),
pythSolFeed: new web3_js_1.PublicKey(pool.oracleSolUsd),
authority,
poolOwner,
vault: (0, pda_utils_1.findPoolVaultPda)(poolOwner),
request: args.loanRequestAddress,
whitelist: (0, pda_utils_1.getWhitelistPda)(loanRequestAccount.mint),
rainTa: (0, tools_utils_1.getAtaForMint)(new web3_js_1.PublicKey(pool.currency), constant_1.RAIN_FEES_ADDRESS),
metadataProgram: constant_1.METADATA_PROGRAM_ID,
instructions: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
authorizationRulesProgram: constant_1.AUTH_PROGRAM_ID,
associatedTokenProgram: constant_1.SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
lookupTable: args.lookupTable ? args.lookupTable : constant_1.RAIN_PROGRAM,
}, {
collectionId: collectionId,
duration: args.duration,
interest: args.interest,
amountInLamports: args.amount,
slippage: args.slippage,
whitelistIndex
}),
];
isPnft &&
(ixs === null || ixs === void 0 ? void 0 : ixs[0].keys.push(...[
{
isSigner: false,
isWritable: true,
pubkey: (0, pda_utils_1.findTokenRecordPDA)(loanRequestAccount === null || loanRequestAccount === void 0 ? void 0 : loanRequestAccount.mint, nftAta),
},
{
isSigner: false,
isWritable: true,
pubkey: (0, pda_utils_1.findTokenRecordPDA)(loanRequestAccount === null || loanRequestAccount === void 0 ? void 0 : loanRequestAccount.mint, vaultTokenAccount),
},
{
isSigner: false,
isWritable: false,
pubkey: ruleSet,
},
]));
if (spl_token_1.NATIVE_MINT.equals(new web3_js_1.PublicKey(pool.currency))) {
ixs.unshift(additionalComputeBudgetInstruction, ...(yield (0, tools_utils_1.withWrappedSol)(connection, publicKey, signerTa)));
ixs.push((0, spl_token_1.createCloseAccountInstruction)(signerTa, publicKey, publicKey));
}
else {
const addAta = yield (0, tools_utils_1.initAtaIfNeeded)(connection, publicKey, signerTa, new web3_js_1.PublicKey(pool.currency));
addAta && ixs.unshift(addAta);
ixs.unshift(additionalComputeBudgetInstruction);
}
return {
instruction: ixs,
signers: loan,
};
});
}
exports.executeLoanRequest = executeLoanRequest;
function configMortgage(publicKey, args) {
return __awaiter(this, void 0, void 0, function* () {
return instructions.createUpdatePoolMortgageInstruction({
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
pool: (0, pda_utils_1.findPoolPda)(publicKey),
referrer: constant_1.RAIN_PROGRAM,
}, args);
});
}
exports.configMortgage = configMortgage;
function buyMortgage(connection, publicKey, args) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h;
const loan = new web3_js_1.Keypair();
const collectionId = yield (0, tools_utils_1.getGlobalOfferIdFromMint)(connection, args.nftMint);
const authority = (0, pda_utils_1.findAuthorityPda)(args.poolOwner);
const vaultTokenAccount = (0, tools_utils_1.getAtaForMint)(args.nftMint, authority);
const poolAddress = (0, pda_utils_1.findPoolPda)(args.poolOwner);
const metadataAddress = (0, tools_utils_1.getMetadataAddress)(args.nftMint);
// const pool = parsePoolAccount((await Pool.fromAccountAddress(connection, poolAddress)).pretty())
// const ltv = pool.collections.find(x => x.collection == collectionId)?.collectionLtv || 0
const createBuyInstructionAccounts = {
signer: publicKey,
signerStats: (0, pda_utils_1.findSignerStatsPda)(publicKey),
vaultTokenAccount,
loan: loan.publicKey,
nftMetadata: metadataAddress,
nftMint: args.nftMint,
collection: (0, pda_utils_1.findCollectionPda)(collectionId),
whitelist: (0, pda_utils_1.getWhitelistPda)(args.nftMint),
poolOwner: args.poolOwner,
pool: (0, pda_utils_1.findPoolPda)(args.poolOwner),
authority,
vault: (0, pda_utils_1.findPoolVaultPda)(args.poolOwner),
wsolVault: (0, pda_utils_1.findWSolSplVaultPda)(args.poolOwner),
nativeMint: spl_token_1.NATIVE_MINT,
rainFees: constant_1.RAIN_FEES_ADDRESS,
associatedTokenProgram: constant_1.SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
};
const additionalComputeBudgetInstruction = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({
units: 1000000,
});
if (args.marketplace == "solanart") {
const buyIx = (yield (0, solanart_1.buyEscrow)(connection, authority, args.nftMint.toBase58(), args.price / 1000000000)).buyIx;
const programMeta = {
pubkey: buyIx.programId,
isSigner: false,
isWritable: false,
};
const mortgageBuyIx = instructions.createTakeMortgageInstruction(createBuyInstructionAccounts, {
collectionId,
marketplace: generated_1.Marketplace.Solanart,
price: args.price,
interest: args.interest,
slippage: args.slippage,
amountInLamports: args.amount,
duration: args.duration,
data: buyIx.data,
});
// set signer false for vault
for (let i = 0; i < buyIx.keys.length; i++) {
// console.log(solanartInstruction.keys[i].pubkey.toBase58())
if (buyIx.keys[i].pubkey.toBase58() == authority.toBase58()) {
buyIx.keys[i].isSigner = false;
}
}
mortgageBuyIx.keys.push(...[programMeta, ...buyIx.keys]);
return {
instruction: [additionalComputeBudgetInstruction, mortgageBuyIx],
signers: loan,
};
}
else if (args.marketplace === "hadeswap" && args.escrowAddress) {
const NftPairBox = (yield Promise.resolve().then(() => __importStar(require("./marketplaces/hadeswap/generatedHades/accounts/nftPairBox")))).NftPairBox;
const NftSwapPair = (yield Promise.resolve().then(() => __importStar(require("./marketplaces/hadeswap/generatedHades/accounts/nftSwapPair")))).NftSwapPair;
const buyHadeswap = (yield Promise.resolve().then(() => __importStar(require("./marketplaces/hadeswap/hadeswap")))).buyHadeswap;
const nftPairBoxData = yield NftPairBox.fromAccountAddress(connection, args.escrowAddress);
const hadesPoolData = yield NftSwapPair.fromAccountAddress(connection, nftPairBoxData.pair);
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const ruleSet = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.programmableConfig) === null || _a === void 0 ? void 0 : _a.ruleSet;
const ruleSetMeta = {
pubkey: ruleSet || constant_1.METADATA_PROGRAM_ID,
isSigner: false,
isWritable: false,
};
const creators = (_b = metadata === null || metadata === void 0 ? void 0 : metadata.data) === null || _b === void 0 ? void 0 : _b.creators;
const buyIx = yield buyHadeswap({
connection: connection,
maxAmountToPay: args.price,
skipFailed: false,
payRoyalty: ruleSet ? true : false,
nftPairBox: args.escrowAddress,
nftMint: args.nftMint,
vaultNftTokenAccount: nftPairBoxData.vaultTokenAccount,
assetReceiver: hadesPoolData.assetReceiver,
protocolFeeReceiver: new web3_js_1.PublicKey("My11111111111111111111111111111111111111111"),
pair: nftPairBoxData.pair,
signer: authority,
instructions: web3_js_1.SYSVAR_INSTRUCTIONS_PUBKEY,
authorizationRulesProgram: constant_1.AUTH_PROGRAM_ID,
editionInfo: (0, pda_utils_1.getNFTEdition)(args.nftMint),
metadataInfo: metadataAddress,
metadataProgram: constant_1.METADATA_PROGRAM_ID,
ownerTokenRecord: (0, pda_utils_1.findTokenRecordPDA)(args.nftMint, nftPairBoxData.vaultTokenAccount),
destTokenRecord: (0, pda_utils_1.findTokenRecordPDA)(args.nftMint, (0, tools_utils_1.getAtaForMint)(args.nftMint, authority)),
hadesPoolData,
});
const programMeta = {
pubkey: buyIx.programId,
isSigner: false,
isWritable: false,
};
const mortgageBuyIx = instructions.createTakeMortgageInstruction(createBuyInstructionAccounts, {
collectionId,
marketplace: generated_1.Marketplace.Hadeswap,
interest: args.interest,
slippage: args.slippage,
price: args.price,
amountInLamports: args.amount,
duration: args.duration,
data: buyIx.data,
});
for (let i = 0; i < buyIx.keys.length; i++) {
if (buyIx.keys[i].pubkey.toBase58() == authority.toBase58()) {
buyIx.keys[i].isSigner = false;
}
}
const creatorAccountMetas = creators
? creators === null || creators === void 0 ? void 0 : creators.filter((creator) => creator.share > 0).map((creator) => ({
pubkey: creator.address,
isSigner: false,
isWritable: true,
}))
: [];
mortgageBuyIx.keys.push(...[programMeta, ...buyIx.keys, ruleSetMeta, ...creatorAccountMetas]);
return {
instruction: [additionalComputeBudgetInstruction, mortgageBuyIx],
signers: loan,
};
}
else if (args.marketplace === "tensorswap_order" && args.escrowAddress) {
const tensorTx = (yield axios_1.default.get(`https://api.rain.fi/marketplace/tensor_swap_tx?buyer=${authority === null || authority === void 0 ? void 0 : authority.toBase58()}&mint=${args.nftMint}&pool=${args.escrowAddress}&maxPriceLamports=${args.price}`)).data;
const buyIx = web3_js_1.Transaction.from(tensorTx[0].tx.data).instructions.find((x) => x.programId.toBase58() == "TSWAPaqyCSx2KABk68Shruf4rp7CxcNi8hAsbdwmHbN");
if (!buyIx) {
throw new Error("No instructions found (Tensor)");
}
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const ruleSet = (_c = metadata === null || metadata === void 0 ? void 0 : metadata.programmableConfig) === null || _c === void 0 ? void 0 : _c.ruleSet;
const ruleSetMeta = {
pubkey: ruleSet || constant_1.METADATA_PROGRAM_ID,
isSigner: false,
isWritable: false,
};
const creators = (_d = metadata === null || metadata === void 0 ? void 0 : metadata.data) === null || _d === void 0 ? void 0 : _d.creators;
const programMeta = {
pubkey: buyIx.programId,
isSigner: false,
isWritable: false,
};
const mortgageBuyIx = instructions.createTakeMortgageInstruction(createBuyInstructionAccounts, {
collectionId,
marketplace: generated_1.Marketplace.TensorswapOrder,
interest: args.interest,
slippage: args.slippage,
price: args.price,
amountInLamports: args.amount,
duration: args.duration,
data: buyIx.data,
});
for (let i = 0; i < buyIx.keys.length; i++) {
if (buyIx.keys[i].pubkey.toBase58() == authority.toBase58()) {
buyIx.keys[i].isSigner = false;
}
}
const creatorAccountMetas = creators
? creators === null || creators === void 0 ? void 0 : creators.filter((creator) => creator.share > 0).map((creator) => ({
pubkey: creator.address,
isSigner: false,
isWritable: true,
}))
: [];
mortgageBuyIx.keys.push(...[programMeta, ...buyIx.keys, ruleSetMeta, ...creatorAccountMetas]);
return {
instruction: [additionalComputeBudgetInstruction, mortgageBuyIx],
signers: loan,
};
}
else if (args.marketplace === "tensorswap_listing") {
const tensorTx = (yield axios_1.default.get(`https://api.rain.fi/marketplace/tensor_buy_tx?buyer=${authority === null || authority === void 0 ? void 0 : authority.toBase58()}&mint=${args.nftMint}&owner=${args.seller}&maxPrice=${args.price}`)).data;
const buyIx = (_e = web3_js_1.Transaction.from(tensorTx[0].tx.data)) === null || _e === void 0 ? void 0 : _e.instructions.find((x) => x.programId.toBase58() == "TSWAPaqyCSx2KABk68Shruf4rp7CxcNi8hAsbdwmHbN");
if (!buyIx) {
throw new Error("No instructions found (Tensor)");
}
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const ruleSet = (_f = metadata === null || metadata === void 0 ? void 0 : metadata.programmableConfig) === null || _f === void 0 ? void 0 : _f.ruleSet;
const ruleSetMeta = {
pubkey: ruleSet || constant_1.METADATA_PROGRAM_ID,
isSigner: false,
isWritable: false,
};
const creators = (_g = metadata === null || metadata === void 0 ? void 0 : metadata.data) === null || _g === void 0 ? void 0 : _g.creators;
const programMeta = {
pubkey: buyIx.programId,
isSigner: false,
isWritable: false,
};
const mortgageBuyIx = instructions.createTakeMortgageInstruction(createBuyInstructionAccounts, {
collectionId,
marketplace: generated_1.Marketplace.TensorswapListing,
interest: args.interest,
slippage: args.slippage,
price: args.price,
amountInLamports: args.amount,
duration: args.duration,
data: buyIx.data,
});
for (let i = 0; i < buyIx.keys.length; i++) {
if (buyIx.keys[i].pubkey.toBase58() == authority.toBase58()) {
buyIx.keys[i].isSigner = false;
}
}
const creatorAccountMetas = creators
? creators === null || creators === void 0 ? void 0 : creators.filter((creator) => creator.share > 0).map((creator) => ({
pubkey: creator.address,
isSigner: false,
isWritable: true,
}))
: [];
mortgageBuyIx.keys.push(...[programMeta, ...buyIx.keys, ruleSetMeta, ...creatorAccountMetas]);
return {
instruction: [additionalComputeBudgetInstruction, mortgageBuyIx],
signers: loan,
};
}
if (args.marketplace == 'magiceden-v2' && args.escrowAddress && args.seller) {
const magicEden = new anchor_1.Program(idl_1.IDL, constant_1.MAGIC_EDEN_PROGRAM_ID, { connection });
const auctionHouse = new web3_js_1.PublicKey("E8cU1WiRWjanGxmn96ewBgk9vPTcL6AEZ1t6F6fkgUWe");
const auctionHouseAuthority = new web3_js_1.PublicKey("autMW8SgBkVYeBgqYiTuJZnkvDZMVU2MHJh9Jh7CSQ2");
const authority = (0, pda_utils_1.findAuthorityPda)(args.poolOwner);
const metadata = yield mpl_token_metadata_1.Metadata.fromAccountAddress(connection, metadataAddress);
const tokenAccount = metadata.tokenStandard == 4 ? (0, tools_utils_1.getAssociatedTokenAddressSync)(args.nftMint, (0, pda_utils_1.getProgramAsSigner)()[0], true) : (0, tools_utils_1.getAtaForMint)(args.nftMint, args.seller);
const auctionHouseData