@rainfi/sdk
Version:
This package is used to interact with Rain.fi protocol on Solana
264 lines • 14.3 kB
JavaScript
;
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.getCurrency = exports.getCurrentInterest = exports.computeDynamicInterest = exports.round = exports.initAtaIfNeeded = exports.withWrappedSol = exports.createSyncNativeInstruction = exports.getAssociatedTokenAddressSync = exports.createAssociatedTokenAccountInstruction = exports.isValidPubkey = exports.getPdaGlobalOfferCollection = exports.getMintFloorPrice = exports.getGlobalOfferIdFromMint = exports.getGlobalOfferIdFromCollection = exports.getAtaForMint = exports.getMetadataAddress = exports.parseEnum = exports.removeNull = void 0;
const web3_js_1 = require("@solana/web3.js");
const layout_utils_1 = require("./layout.utils");
const bn_js_1 = __importDefault(require("bn.js"));
const pda_utils_1 = require("./pda.utils");
const constant_1 = require("./constant");
const metadata_utils_1 = require("./metadata.utils");
const BufferLayout = __importStar(require("@solana/buffer-layout"));
const spl_token_1 = require("@solana/spl-token");
const axios_1 = __importDefault(require("axios"));
function removeNull(array) {
return array.filter((x) => x !== null);
}
exports.removeNull = removeNull;
;
const parseEnum = (o) => Object.keys(o)[0];
exports.parseEnum = parseEnum;
function getMetadataAddress(mintKey) {
const metadataAccount = (web3_js_1.PublicKey.findProgramAddressSync([
Buffer.from('metadata'),
constant_1.METADATA_PROGRAM_ID.toBuffer(),
new web3_js_1.PublicKey(mintKey).toBuffer(),
], constant_1.METADATA_PROGRAM_ID))[0];
return metadataAccount;
}
exports.getMetadataAddress = getMetadataAddress;
const getAtaForMint = (mint, buyer) => {
return web3_js_1.PublicKey.findProgramAddressSync([buyer.toBuffer(), constant_1.TOKEN_PROGRAM_ID.toBuffer(), new web3_js_1.PublicKey(mint).toBuffer()], constant_1.SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID)[0];
};
exports.getAtaForMint = getAtaForMint;
const getGlobalOfferIdFromCollection = (connection, collection) => __awaiter(void 0, void 0, void 0, function* () {
const collectionAddress = yield (0, exports.getPdaGlobalOfferCollection)(collection);
const collectionAccount = (yield connection.getAccountInfo(collectionAddress));
if (!collectionAccount)
throw new Error('No global offer collection found for this NFT');
const decodedCollection = layout_utils_1.COLLECTION_GLOBAL_OFFER_LAYOUT.decode(collectionAccount.data);
return new bn_js_1.default(decodedCollection.collection_id, 10, "le").toNumber();
});
exports.getGlobalOfferIdFromCollection = getGlobalOfferIdFromCollection;
const getGlobalOfferIdFromMint = (connection, nftMint) => __awaiter(void 0, void 0, void 0, function* () {
const whitelistMint = (0, pda_utils_1.getWhitelistPda)(nftMint);
const fetchedAccount = (yield connection.getAccountInfo(whitelistMint));
if (!fetchedAccount) {
const metadataAccount = (yield connection.getAccountInfo(yield getMetadataAddress(nftMint)));
if (!metadataAccount)
throw new Error('No metadata found for this NFT');
const metadata = (0, metadata_utils_1.decodeMetadata)(metadataAccount.data);
if (!metadata.collection || metadata.collection && metadata.collection.key && !metadata.collection.verified)
throw new Error('No verified collection found for this NFT');
const collectionAddress = yield (0, exports.getPdaGlobalOfferCollection)(new web3_js_1.PublicKey(metadata.collection.key));
const collectionAccount = (yield connection.getAccountInfo(collectionAddress));
if (!collectionAccount)
throw new Error('No global offer collection found for this NFT');
const decodedCollection = layout_utils_1.COLLECTION_GLOBAL_OFFER_LAYOUT.decode(collectionAccount.data);
return new bn_js_1.default(decodedCollection.collection_id, 10, "le").toNumber();
}
const decoded = layout_utils_1.GLOBAL_OFFER_WHITELIST_LAYOUT.decode(fetchedAccount.data);
return new bn_js_1.default(decoded.collection_id, 10, "le").toNumber();
});
exports.getGlobalOfferIdFromMint = getGlobalOfferIdFromMint;
const getMintFloorPrice = (connection, id) => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const collectionAddress = yield (0, pda_utils_1.findCollectionPda)(id);
const decodedCollection = layout_utils_1.COLLECTION_ACCOUNT_LAYOUT.decode((_a = (yield connection.getAccountInfo(collectionAddress))) === null || _a === void 0 ? void 0 : _a.data);
return new bn_js_1.default(decodedCollection.floor_price, 10, "le").toNumber();
});
exports.getMintFloorPrice = getMintFloorPrice;
const getPdaGlobalOfferCollection = (collectionAccount) => __awaiter(void 0, void 0, void 0, function* () {
return (yield web3_js_1.PublicKey.findProgramAddress([
Buffer.from('collection'),
collectionAccount.toBuffer(),
web3_js_1.PublicKey.default.toBuffer()
], constant_1.GLOBAL_OFFER_PROGRAM))[0];
});
exports.getPdaGlobalOfferCollection = getPdaGlobalOfferCollection;
const isValidPubkey = (pubkey) => {
try {
new web3_js_1.PublicKey(pubkey);
return true;
}
catch (error) {
return false;
}
};
exports.isValidPubkey = isValidPubkey;
/**
* Construct an AssociatedTokenAccount instruction
*
* @param payer Payer of the initialization fees
* @param associatedToken New associated token account
* @param owner Owner of the new account
* @param mint Token mint account
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Instruction to add to a transaction
*/
function createAssociatedTokenAccountInstruction(payer, associatedToken, owner, mint, programId = constant_1.TOKEN_PROGRAM_ID, associatedTokenProgramId = constant_1.ASSOCIATED_TOKEN_PROGRAM_ID) {
const keys = [
{ pubkey: payer, isSigner: true, isWritable: true },
{ pubkey: associatedToken, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: false, isWritable: false },
{ pubkey: new web3_js_1.PublicKey(mint), isSigner: false, isWritable: false },
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
{ pubkey: web3_js_1.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
];
return new web3_js_1.TransactionInstruction({
keys,
programId: associatedTokenProgramId,
data: Buffer.alloc(0),
});
}
exports.createAssociatedTokenAccountInstruction = createAssociatedTokenAccountInstruction;
/**
* Get the address of the associated token account for a given mint and owner
*
* @param mint Token mint account
* @param owner Owner of the new account
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Address of the associated token account
*/
function getAssociatedTokenAddressSync(mint, owner, allowOwnerOffCurve = false, programId = constant_1.TOKEN_PROGRAM_ID, associatedTokenProgramId = constant_1.ASSOCIATED_TOKEN_PROGRAM_ID) {
if (!allowOwnerOffCurve && !web3_js_1.PublicKey.isOnCurve(owner.toBuffer()))
throw new Error("TokenOwnerOffCurveError");
const [address] = web3_js_1.PublicKey.findProgramAddressSync([owner.toBuffer(), programId.toBuffer(), mint.toBuffer()], associatedTokenProgramId);
return address;
}
exports.getAssociatedTokenAddressSync = getAssociatedTokenAddressSync;
function createSyncNativeInstruction(nativeAccount) {
const dataLayout = BufferLayout.struct([
BufferLayout.u8("instruction"),
]);
const data = Buffer.alloc(dataLayout.span);
dataLayout.encode({
instruction: 17, // SyncNative instruction
}, data);
const keys = [{ pubkey: nativeAccount, isSigner: false, isWritable: true }];
return new web3_js_1.TransactionInstruction({
keys,
programId: constant_1.TOKEN_PROGRAM_ID,
data,
});
}
exports.createSyncNativeInstruction = createSyncNativeInstruction;
function withWrappedSol(connection_1, owner_1, accountAddress_1) {
return __awaiter(this, arguments, void 0, function* (connection, owner, accountAddress, amount = 0) {
const instructions = [
createSyncNativeInstruction(accountAddress),
];
if (amount)
instructions.unshift(web3_js_1.SystemProgram.transfer({
fromPubkey: owner,
toPubkey: accountAddress,
lamports: amount,
}));
if (!(yield connection.getAccountInfo(accountAddress)))
instructions.unshift(createAssociatedTokenAccountInstruction(owner, accountAddress, owner, spl_token_1.NATIVE_MINT));
return instructions;
});
}
exports.withWrappedSol = withWrappedSol;
function initAtaIfNeeded(connection, signer, signerTa, mint) {
return __awaiter(this, void 0, void 0, function* () {
if (!(yield connection.getAccountInfo(signerTa))) {
return createAssociatedTokenAccountInstruction(signer, signerTa, signer, mint);
}
else {
return null;
}
});
}
exports.initAtaIfNeeded = initAtaIfNeeded;
function round(value, decimals = 3) {
return Math.round(value * Math.pow(10, decimals || 0)) / Math.pow(10, decimals || 0);
}
exports.round = round;
const computeDynamicInterest = (kind, interest, createdAt, duration) => {
if (kind == "mortgage")
return interest === null || interest === void 0 ? void 0 : interest.toNumber();
const currentTimestamp = new bn_js_1.default(Math.round(+new Date() / 1000));
const timeElapsed = currentTimestamp
.sub(createdAt)
.div(new bn_js_1.default(3600))
.add(new bn_js_1.default(1));
let dynamicInterest = timeElapsed
.mul(interest)
.div(duration.div(new bn_js_1.default(3600)));
if (dynamicInterest.lt(new bn_js_1.default(30).mul(interest).div(new bn_js_1.default(100)))) {
dynamicInterest = new bn_js_1.default(30).mul(interest).div(new bn_js_1.default(100));
}
return dynamicInterest === null || dynamicInterest === void 0 ? void 0 : dynamicInterest.toNumber();
};
exports.computeDynamicInterest = computeDynamicInterest;
function getCurrentInterest(loan, loanDecimals) {
var _a;
const interest = loan === null || loan === void 0 ? void 0 : loan.interest;
const totalInterestPercent = round(interest * 100 / (loan === null || loan === void 0 ? void 0 : loan.amount), 2);
let dynamicInterest = (loan === null || loan === void 0 ? void 0 : loan.duration) && (0, exports.computeDynamicInterest)(loan === null || loan === void 0 ? void 0 : loan.kind, new bn_js_1.default(loan.interest), new bn_js_1.default(loan.createdAt), new bn_js_1.default(loan.duration));
const currentInterestPercent = dynamicInterest * 100 / (loan === null || loan === void 0 ? void 0 : loan.amount);
const interestWFees = dynamicInterest && ((_a = (new bn_js_1.default(dynamicInterest).sub(new bn_js_1.default(dynamicInterest).mul(new bn_js_1.default(500)).div(new bn_js_1.default(10000))))) === null || _a === void 0 ? void 0 : _a.toNumber());
const finalAmount = (loan === null || loan === void 0 ? void 0 : loan.amount) + round((((dynamicInterest / loanDecimals) + 0.1) * loanDecimals), 0);
return {
currentInterest: dynamicInterest / loanDecimals,
currentInterestPercent: round(currentInterestPercent, 2),
currentInterestRounded: round(dynamicInterest / loanDecimals, 3),
totalInterest: interest / loanDecimals,
totalInterestPercent: round(totalInterestPercent, 2),
totalInterestRounded: round(interest / loanDecimals, 3),
interestWFees,
finalAmount
};
}
exports.getCurrentInterest = getCurrentInterest;
function getCurrency(currency) {
return __awaiter(this, void 0, void 0, function* () {
const currencyInfo = (yield axios_1.default.get(`https://api.rain.fi/tokens/${currency}`)).data;
if (!currencyInfo)
throw new Error(`Currency not found ${currency}`);
return currencyInfo;
});
}
exports.getCurrency = getCurrency;
//# sourceMappingURL=tools.utils.js.map