@flipflop-sdk/node
Version:
FlipFlop Node.js SDK for programmatic token operations
710 lines • 30.8 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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLookupTable = exports.createAddressLookupTable = exports.getURCDetails = exports.getReferralDataByCodeHash = exports.getMetadataByMint = exports.getOrcleAccountAddress = exports.getPoolLpMintAddress = exports.getPoolVaultAddress = exports.getPoolAddress = exports.getAuthAddress = exports.compareMints = exports.processVersionedTransaction = exports.mintBy = exports.getLegacyTokenMetadata = exports.parseConfigData = exports.cleanTokenName = exports.loadKeypairFromBase58 = exports.getSolanaBalance = exports.checkAccountExists = exports.loadKeypairFromFile = exports.getTokenBalance = exports.initProviderNoSigner = exports.initProvider = void 0;
const web3_js_1 = require("@solana/web3.js");
const fs_1 = __importDefault(require("fs"));
const bs58_1 = __importDefault(require("bs58"));
const anchor_1 = require("@coral-xyz/anchor");
const token_1 = require("@coral-xyz/anchor/dist/cjs/utils/token");
const spl_token_1 = require("@solana/spl-token");
const constants_1 = require("./constants");
const system_1 = require("@coral-xyz/anchor/dist/cjs/native/system");
const config_1 = require("./config");
const sleep_promise_1 = __importDefault(require("sleep-promise"));
const initProvider = async (rpc, account) => {
const wallet = {
publicKey: account.publicKey,
signTransaction: async (tx) => {
tx.sign(account);
return tx;
},
signAllTransactions: async (txs) => {
txs.forEach((tx) => tx.sign(account));
return txs;
},
};
const provider = new anchor_1.AnchorProvider(rpc, wallet, {
commitment: "confirmed",
});
try {
const networkType = (0, config_1.getNetworkType)(rpc.rpcEndpoint);
const idlModule = await Promise.resolve(`${`./idl/fair_mint_token_${networkType}.json`}`).then(s => __importStar(require(s)));
const idl = idlModule.default || idlModule;
const program = new anchor_1.Program(idl, provider);
const config = config_1.CONFIGS[(0, config_1.getNetworkType)(rpc.rpcEndpoint)];
const programId = new web3_js_1.PublicKey(config.programId);
return {
program,
provider,
programId,
};
}
catch (error) {
throw new Error(`Failed to load IDL for network ${(0, config_1.getNetworkType)(rpc.rpcEndpoint)}: ${error}`);
}
};
exports.initProvider = initProvider;
const initProviderNoSigner = async (rpc) => {
const wallet = {
publicKey: web3_js_1.PublicKey.default,
signTransaction: async (tx) => tx,
signAllTransactions: async (txs) => txs,
};
const provider = new anchor_1.AnchorProvider(rpc, wallet, {
commitment: "confirmed",
});
try {
const networkType = (0, config_1.getNetworkType)(rpc.rpcEndpoint);
const idlModule = await Promise.resolve(`${`./idl/fair_mint_token_${networkType}.json`}`).then(s => __importStar(require(s)));
const idl = idlModule.default || idlModule;
const program = new anchor_1.Program(idl, provider);
const config = config_1.CONFIGS[(0, config_1.getNetworkType)(rpc.rpcEndpoint)];
const programId = new web3_js_1.PublicKey(config.programId);
return {
program,
provider,
programId,
};
}
catch (error) {
throw new Error(`Failed to load IDL for network ${(0, config_1.getNetworkType)(rpc.rpcEndpoint)}: ${error}`);
}
};
exports.initProviderNoSigner = initProviderNoSigner;
const getTokenBalance = async (publicKey, connection) => {
const balance = await connection.getTokenAccountBalance(publicKey);
return balance.value.uiAmount;
};
exports.getTokenBalance = getTokenBalance;
// Load keypair from file (supports .pri or JSON format)
const loadKeypairFromFile = (filePath) => {
try {
const fileContent = fs_1.default.readFileSync(filePath, "utf8");
const secretKeyArray = JSON.parse(fileContent);
if (!Array.isArray(secretKeyArray)) {
throw new Error("Private key file must contain an array of numbers");
}
if (secretKeyArray.length !== 64) {
throw new Error("Private key array must contain exactly 64 numbers");
}
const secretKey = new Uint8Array(secretKeyArray);
return web3_js_1.Keypair.fromSecretKey(secretKey);
}
catch (error) {
throw new Error(`Failed to load keypair from file ${filePath}: ${error.message}`);
}
};
exports.loadKeypairFromFile = loadKeypairFromFile;
// Check if an account exists on-chain
const checkAccountExists = async (rpc, account) => {
const info = await rpc.getAccountInfo(account);
return info !== null;
};
exports.checkAccountExists = checkAccountExists;
// Get SOL balance
const getSolanaBalance = async (rpc, account) => {
return await rpc.getBalance(account);
};
exports.getSolanaBalance = getSolanaBalance;
// Utility to load single keypair from base58 string
const loadKeypairFromBase58 = (base58Key) => {
const secretKey = bs58_1.default.decode(base58Key.trim());
return web3_js_1.Keypair.fromSecretKey(secretKey);
};
exports.loadKeypairFromBase58 = loadKeypairFromBase58;
const cleanTokenName = (str) => {
return str.replace(/\x00/g, "").trim();
};
exports.cleanTokenName = cleanTokenName;
const parseConfigData = async (program, configAccount) => {
return new Promise((resolve, reject) => {
program.account.tokenConfigData.fetch(configAccount).then((configData) => {
try {
resolve({
admin: configData.admin,
// feeVault: configData.feeVault.toBase58(),
feeRate: configData.feeRate.toNumber() / 1000000000,
maxSupply: new anchor_1.BN(configData.maxSupply)
.div(new anchor_1.BN("1000000000"))
.toNumber(),
targetEras: configData.targetEras,
initialMintSize: new anchor_1.BN(configData.initialMintSize)
.div(new anchor_1.BN("1000000000"))
.toNumber(),
epochesPerEra: new anchor_1.BN(configData.epochesPerEra).toNumber(),
targetSecondsPerEpoch: new anchor_1.BN(configData.targetSecondsPerEpoch).toNumber(),
reduceRatio: configData.reduceRatio,
tokenVault: configData.tokenVault,
wsolVault: configData.wsolVault,
liquidityTokensRatio: configData.liquidityTokensRatio,
supply: new anchor_1.BN(configData.mintStateData.supply)
.div(new anchor_1.BN("1000000000"))
.toNumber(),
currentEra: configData.mintStateData.currentEra,
currentEpoch: configData.mintStateData.currentEpoch.toNumber(),
elapsedSecondsEpoch: configData.mintStateData.elapsedSecondsEpoch.toNumber(),
startTimestampEpoch: configData.mintStateData.startTimestampEpoch.toNumber(),
difficultyCoefficient: configData.mintStateData.difficultyCoefficientEpoch,
lastDifficultyCoefficient: configData.mintStateData.lastDifficultyCoefficientEpoch,
mintSizeEpoch: new anchor_1.BN(configData.mintStateData.mintSizeEpoch)
.div(new anchor_1.BN("1000000000"))
.toNumber(),
quantityMintedEpoch: new anchor_1.BN(configData.mintStateData.quantityMintedEpoch)
.div(new anchor_1.BN("1000000000"))
.toNumber(),
targetMintSizeEpoch: new anchor_1.BN(configData.mintStateData.targetMintSizeEpoch)
.div(new anchor_1.BN("1000000000"))
.toNumber(),
graduateEpoch: configData.mintStateData.graduateEpoch,
});
}
catch (error) {
console.error(error);
reject(error);
}
});
});
};
exports.parseConfigData = parseConfigData;
const getLegacyTokenMetadata = async (connection, metadataAccountPda, debug = false) => {
try {
const metadataAccountInfo = await connection.getAccountInfo(metadataAccountPda);
if (!metadataAccountInfo) {
throw new Error("Metadata account not found");
}
const data = metadataAccountInfo.data;
// Parse key (1 byte)
const key = data[0];
// Parse update authority (32 bytes)
const updateAuthority = new web3_js_1.PublicKey(data.slice(1, 33));
// Parse mint (32 bytes)
const mint = new web3_js_1.PublicKey(data.slice(33, 65));
// Parse name
const nameLength = data.readUInt32LE(65);
let currentPos = 69;
const name = data
.slice(currentPos, currentPos + nameLength)
.toString("utf8");
currentPos += nameLength;
// Parse symbol
const symbolLength = data.readUInt32LE(currentPos);
currentPos += 4;
const symbol = data
.slice(currentPos, currentPos + symbolLength)
.toString("utf8");
currentPos += symbolLength;
// Parse uri
const uriLength = data.readUInt32LE(currentPos);
currentPos += 4;
const uri = data.slice(currentPos, currentPos + uriLength).toString("utf8");
currentPos += uriLength;
// Parse seller fee basis points (2 bytes)
const sellerFeeBasisPoints = data.readUInt16LE(currentPos);
currentPos += 2;
// Parse creators
const hasCreators = data[currentPos];
currentPos += 1;
let creators = [];
if (hasCreators) {
const creatorsLength = data.readUInt32LE(currentPos);
currentPos += 4;
for (let i = 0; i < creatorsLength; i++) {
const creatorAddress = new web3_js_1.PublicKey(data.slice(currentPos, currentPos + 32));
currentPos += 32;
const verified = data[currentPos] === 1;
currentPos += 1;
const share = data[currentPos];
currentPos += 1;
creators.push({ address: creatorAddress, verified, share });
}
}
// Parse collection
const hasCollection = data[currentPos];
currentPos += 1;
let collection = null;
if (hasCollection) {
const collectionKey = new web3_js_1.PublicKey(data.slice(currentPos, currentPos + 32));
currentPos += 32;
const verified = data[currentPos] === 1;
currentPos += 1;
collection = { key: collectionKey, verified };
}
// Finally, parse isMutable
const isMutable = data[currentPos] === 1;
// Log the parsed metadata
const result = {
success: true,
key,
updateAuthority: updateAuthority.toBase58(),
mint: mint.toBase58(),
data: {
name,
symbol,
uri,
sellerFeeBasisPoints,
creators: creators.map((c) => ({
address: c.address.toBase58(),
verified: c.verified,
share: c.share,
})),
},
isMutable,
collection: collection
? {
key: collection.key.toBase58(),
verified: collection.verified,
}
: null,
};
if (debug)
console.log("Parsed Metadata:", result);
return result;
}
catch (error) {
console.error("Error fetching metadata:", error);
return {
success: false,
message: error.message,
};
}
};
exports.getLegacyTokenMetadata = getLegacyTokenMetadata;
const mintBy = async (provider, program, mintAccount, configAccount, referralAccount, referrerMain, tokenMetadata, codeHash, account, systemConfigAccount, connection, lookupTableAddress, protocolFeeAccount) => {
// check balance SOL
let balance = await (0, exports.getSolanaBalance)(connection, account.publicKey);
if (balance == 0) {
return {
success: false,
message: "Balance not enough",
};
}
const destination = await (0, spl_token_1.getOrCreateAssociatedTokenAccount)(connection, account, mintAccount, account.publicKey, false, undefined, undefined, token_1.TOKEN_PROGRAM_ID);
const mintTokenVaultAta = await (0, spl_token_1.getAssociatedTokenAddress)(mintAccount, mintAccount, true, token_1.TOKEN_PROGRAM_ID);
const tokenVaultAta = await (0, spl_token_1.getAssociatedTokenAddress)(mintAccount, configAccount, true, token_1.TOKEN_PROGRAM_ID);
const referrerAta = await (0, spl_token_1.getAssociatedTokenAddress)(mintAccount, referrerMain, false, token_1.TOKEN_PROGRAM_ID);
const programId = new web3_js_1.PublicKey(config_1.CONFIGS[(0, config_1.getNetworkType)(connection.rpcEndpoint)].programId);
const [refundAccount] = web3_js_1.PublicKey.findProgramAddressSync([
Buffer.from(constants_1.REFUND_SEEDS),
mintAccount.toBuffer(),
account.publicKey.toBuffer(),
], programId);
const accountInfo = await connection.getAccountInfo(referrerAta);
if (accountInfo === null) {
return {
success: false,
message: "Referrer ata not exist",
};
}
const beforeBalance = (await connection.getTokenAccountBalance(destination.address)).value.uiAmount;
const codeHashInReferralAccount = await program.account.tokenReferralData.fetch(referralAccount);
if (codeHashInReferralAccount.codeHash.toBase58() !== codeHash.toBase58()) {
return {
success: false,
message: "Code hash not match",
};
}
const protocolWsolVault = await (0, spl_token_1.getOrCreateAssociatedTokenAccount)(provider.connection, account, spl_token_1.NATIVE_MINT, protocolFeeAccount, false, undefined, undefined, token_1.TOKEN_PROGRAM_ID);
const wsolVaultAta = await (0, spl_token_1.getAssociatedTokenAddress)(spl_token_1.NATIVE_MINT, configAccount, true, token_1.TOKEN_PROGRAM_ID);
const destinationWsolAta = await (0, spl_token_1.getAssociatedTokenAddress)(spl_token_1.NATIVE_MINT, account.publicKey, false, token_1.TOKEN_PROGRAM_ID);
let token0Mint = mintAccount;
let token1Mint = spl_token_1.NATIVE_MINT;
let token0Program = token_1.TOKEN_PROGRAM_ID;
let token1Program = token_1.TOKEN_PROGRAM_ID;
if ((0, exports.compareMints)(token0Mint, token1Mint) > 0) {
[token0Mint, token1Mint] = [token1Mint, token0Mint];
[token0Program, token1Program] = [token1Program, token0Program];
}
const rpcUrl = connection.rpcEndpoint;
const network = (0, config_1.getNetworkType)(rpcUrl);
const cpSwapProgram = new web3_js_1.PublicKey(config_1.CONFIGS[network].cpSwapProgram);
const cpSwapConfigAddress = new web3_js_1.PublicKey(config_1.CONFIGS[network].cpSwapConfigAddress);
const createPoolFeeReceive = new web3_js_1.PublicKey(config_1.CONFIGS[network].createPoolFeeReceive);
const [authority] = (0, exports.getAuthAddress)(cpSwapProgram);
const [poolAddress] = (0, exports.getPoolAddress)(cpSwapConfigAddress, token0Mint, token1Mint, cpSwapProgram);
const [lpMintAddress] = (0, exports.getPoolLpMintAddress)(poolAddress, cpSwapProgram);
const [vault0] = (0, exports.getPoolVaultAddress)(poolAddress, token0Mint, cpSwapProgram);
const [vault1] = (0, exports.getPoolVaultAddress)(poolAddress, token1Mint, cpSwapProgram);
const [observationAddress] = (0, exports.getOrcleAccountAddress)(poolAddress, cpSwapProgram);
const creatorLpTokenAddress = (0, spl_token_1.getAssociatedTokenAddressSync)(lpMintAddress, account.publicKey, false, token_1.TOKEN_PROGRAM_ID);
const creatorToken0 = (0, spl_token_1.getAssociatedTokenAddressSync)(token0Mint, account.publicKey, false, token0Program);
const creatorToken1 = (0, spl_token_1.getAssociatedTokenAddressSync)(token1Mint, account.publicKey, false, token1Program);
const context = {
mint: mintAccount,
destination: destination.address,
destinationWsolAta: destinationWsolAta,
refundAccount: refundAccount,
user: account.publicKey,
configAccount: configAccount,
systemConfigAccount: systemConfigAccount,
mintTokenVault: mintTokenVaultAta,
tokenVault: tokenVaultAta,
wsolVault: wsolVaultAta,
wsolMint: spl_token_1.NATIVE_MINT,
referrerAta: referrerAta,
referrerMain: referrerMain,
referralAccount: referralAccount,
protocolFeeAccount,
protocolWsolVault: protocolWsolVault.address,
poolState: poolAddress,
ammConfig: cpSwapConfigAddress,
cpSwapProgram: cpSwapProgram,
token0Mint: token0Mint,
token1Mint: token1Mint,
};
// console.log("mint token data", Object.fromEntries(
// Object.entries(context).map(([key, value]) => [key, value.toString()])
// ));
// =============== Use RemainingAccounts for initializing pool accounts, total 21 accounts ===============
const remainingAccounts = [
{
pubkey: cpSwapProgram, // <- 1
isWritable: false,
isSigner: false,
},
{
pubkey: account.publicKey, // <- 2
isWritable: true,
isSigner: true,
},
{
pubkey: cpSwapConfigAddress, // <- 3
isWritable: true,
isSigner: false,
},
{
pubkey: authority, // <- 4
isWritable: true,
isSigner: false,
},
{
pubkey: poolAddress, // <- 5
isWritable: true,
isSigner: false,
},
{
pubkey: token0Mint, // <- 6
isWritable: true,
isSigner: false,
},
{
pubkey: token1Mint, // <- 7
isWritable: true,
isSigner: false,
},
{
pubkey: lpMintAddress, // <- 8
isWritable: true,
isSigner: false,
},
{
pubkey: creatorToken0, // <- 9
isWritable: true,
isSigner: false,
},
{
pubkey: creatorToken1, // <- 10
isWritable: true,
isSigner: false,
},
{
pubkey: creatorLpTokenAddress, // <- 11
isWritable: true,
isSigner: false,
},
{
pubkey: vault0, // <- 12
isWritable: true,
isSigner: false,
},
{
pubkey: vault1, // <- 13
isWritable: true,
isSigner: false,
},
{
pubkey: createPoolFeeReceive, // <- 14
isWritable: true,
isSigner: false,
},
{
pubkey: observationAddress, // <- 15
isWritable: true,
isSigner: false,
},
{
pubkey: token_1.TOKEN_PROGRAM_ID, // <- 16
isWritable: true,
isSigner: false,
},
{
pubkey: token0Program, // <- 17
isWritable: true,
isSigner: false,
},
{
pubkey: token1Program, // <- 18
isWritable: true,
isSigner: false,
},
{
pubkey: token_1.ASSOCIATED_PROGRAM_ID, // <- 19
isWritable: true,
isSigner: false,
},
{
pubkey: system_1.SYSTEM_PROGRAM_ID, // <- 20
isWritable: true,
isSigner: false,
},
{
pubkey: constants_1.RENT_PROGRAM_ID, // <- 21
isWritable: true,
isSigner: false,
},
];
// ===================================================================================
try {
const ix0 = web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: 500000 }); // or use --compute-unit-limit 400000 to run solana-test-validator
const ix = await program.methods
.mintTokens(tokenMetadata.name, tokenMetadata.symbol, codeHash.toBuffer())
.accounts(context)
.remainingAccounts(remainingAccounts)
.instruction();
// Create versioned transaction with LUT
const accountInfo = await connection.getAccountInfo(lookupTableAddress);
if (!accountInfo) {
return {
success: false,
message: "Lookup table account not found",
};
}
const lookupTable = new web3_js_1.AddressLookupTableAccount({
key: lookupTableAddress,
state: web3_js_1.AddressLookupTableAccount.deserialize(accountInfo.data),
});
const messageV0 = new web3_js_1.VersionedTransaction(new web3_js_1.TransactionMessage({
payerKey: account.publicKey,
recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
instructions: [ix0, ix],
}).compileToV0Message([lookupTable]));
const result = await (0, exports.processVersionedTransaction)(messageV0, connection, account, "confirmed");
return {
success: true,
message: "Mint succeeded",
data: {
owner: account.publicKey,
tokenAccount: destination.address,
tx: result.data?.tx || "",
},
};
}
catch (e) {
return {
success: false,
message: `Mint failed: ${e instanceof Error ? e.message : "Unknown error"}`,
};
}
};
exports.mintBy = mintBy;
const processVersionedTransaction = async (messageV0, connection, wallet, confirmLevel = "confirmed") => {
messageV0.sign([wallet]);
const signature = await connection.sendTransaction(messageV0, {
skipPreflight: false,
});
const latestBlockhash = await connection.getLatestBlockhash();
const status = await connection.confirmTransaction({
signature,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
}, confirmLevel);
if (status.value.err) {
return {
success: false,
message: `Mint failed: ${JSON.stringify(status.value.err)}`,
};
}
return {
success: true,
message: `Mint succeeded`,
data: {
tx: signature,
},
};
};
exports.processVersionedTransaction = processVersionedTransaction;
const compareMints = (mintA, mintB) => {
const bufferA = mintA.toBuffer();
const bufferB = mintB.toBuffer();
for (let i = 0; i < bufferA.length; i++) {
if (bufferA[i] !== bufferB[i]) {
return bufferA[i] - bufferB[i];
}
}
return 0;
};
exports.compareMints = compareMints;
const getAuthAddress = (programId) => {
const [address, bump] = web3_js_1.PublicKey.findProgramAddressSync([constants_1.POOL_AUTH_SEED], programId);
return [address, bump];
};
exports.getAuthAddress = getAuthAddress;
const getPoolAddress = (ammConfig, tokenMint0, tokenMint1, programId) => {
const [address, bump] = web3_js_1.PublicKey.findProgramAddressSync([
constants_1.POOL_SEED,
ammConfig.toBuffer(),
tokenMint0.toBuffer(),
tokenMint1.toBuffer(),
], programId);
return [address, bump];
};
exports.getPoolAddress = getPoolAddress;
const getPoolVaultAddress = (pool, vaultTokenMint, programId) => {
const [address, bump] = web3_js_1.PublicKey.findProgramAddressSync([constants_1.POOL_VAULT_SEED, pool.toBuffer(), vaultTokenMint.toBuffer()], programId);
return [address, bump];
};
exports.getPoolVaultAddress = getPoolVaultAddress;
const getPoolLpMintAddress = (pool, programId) => {
const [address, bump] = web3_js_1.PublicKey.findProgramAddressSync([constants_1.POOL_LPMINT_SEED, pool.toBuffer()], programId);
return [address, bump];
};
exports.getPoolLpMintAddress = getPoolLpMintAddress;
const getOrcleAccountAddress = (pool, programId) => {
const [address, bump] = web3_js_1.PublicKey.findProgramAddressSync([constants_1.ORACLE_SEED, pool.toBuffer()], programId);
return [address, bump];
};
exports.getOrcleAccountAddress = getOrcleAccountAddress;
const getMetadataByMint = async (rpc, mintAccount) => {
const [metadataAccountPda] = web3_js_1.PublicKey.findProgramAddressSync([
Buffer.from(constants_1.METADATA_SEED),
constants_1.TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mintAccount.toBuffer(),
], constants_1.TOKEN_METADATA_PROGRAM_ID);
return await (0, exports.getLegacyTokenMetadata)(rpc, metadataAccountPda);
};
exports.getMetadataByMint = getMetadataByMint;
const getReferralDataByCodeHash = async (connection, program, codeHash) => {
const programId = new web3_js_1.PublicKey(config_1.CONFIGS[(0, config_1.getNetworkType)(connection.rpcEndpoint)].programId);
const [codeAccountPda] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from(constants_1.CODE_ACCOUNT_SEED), codeHash.toBuffer()], programId);
const codeAccountInfo = await connection.getAccountInfo(codeAccountPda);
if (!codeAccountInfo) {
return {
success: false,
message: "Code account does not exist",
};
}
const codeAccountData = await program.account.codeAccountData.fetch(codeAccountPda);
const referralAccountPda = codeAccountData.referralAccount;
const referralAccountInfo = await connection.getAccountInfo(referralAccountPda);
if (!referralAccountInfo) {
return {
success: false,
message: "Referral account does not exist",
};
}
const referralAccountData = await program.account.tokenReferralData.fetch(referralAccountPda);
return {
success: true,
data: {
...referralAccountData,
referralAccount: referralAccountPda,
},
};
};
exports.getReferralDataByCodeHash = getReferralDataByCodeHash;
const getURCDetails = async (connection, program, urcCode) => {
const programId = new web3_js_1.PublicKey(config_1.CONFIGS[(0, config_1.getNetworkType)(connection.rpcEndpoint)].programId);
const [codeHash] = web3_js_1.PublicKey.findProgramAddressSync([Buffer.from(constants_1.REFERRAL_CODE_SEED), Buffer.from(urcCode)], programId);
const _referralData = await (0, exports.getReferralDataByCodeHash)(connection, program, codeHash);
if (!_referralData.success) {
throw new Error("Fail to get URC data, please use another one.");
}
return _referralData.data;
};
exports.getURCDetails = getURCDetails;
const createAddressLookupTable = async (connection, payer, addresses) => {
const slot = await connection.getSlot("finalized"); // not "confirmed"
// Create instruction for Address Lookup Table
const [createIx, lutAddress] = web3_js_1.AddressLookupTableProgram.createLookupTable({
authority: payer.publicKey,
payer: payer.publicKey,
recentSlot: slot,
});
// Create instruction to extend Address Lookup Table
const extendIx = web3_js_1.AddressLookupTableProgram.extendLookupTable({
payer: payer.publicKey,
authority: payer.publicKey,
lookupTable: lutAddress,
addresses,
});
// Create and send transaction
const tx = new web3_js_1.Transaction().add(createIx).add(extendIx);
tx.recentBlockhash = (await connection.getLatestBlockhash("confirmed")).blockhash;
tx.feePayer = payer.publicKey;
await (0, web3_js_1.sendAndConfirmTransaction)(connection, tx, [payer]);
// Wait for confirmation and fetch the table
await (0, sleep_promise_1.default)(1000);
const accountInfo = await connection.getAccountInfo(lutAddress);
return new web3_js_1.AddressLookupTableAccount({
key: lutAddress,
state: web3_js_1.AddressLookupTableAccount.deserialize(accountInfo.data),
});
};
exports.createAddressLookupTable = createAddressLookupTable;
const createLookupTable = async (connection, payer) => {
const rpc = connection.rpcEndpoint;
const network = (0, config_1.getNetworkType)(rpc);
const addresses = [
token_1.TOKEN_PROGRAM_ID,
spl_token_1.TOKEN_2022_PROGRAM_ID,
system_1.SYSTEM_PROGRAM_ID,
constants_1.RENT_PROGRAM_ID,
token_1.ASSOCIATED_PROGRAM_ID,
spl_token_1.NATIVE_MINT,
new web3_js_1.PublicKey(config_1.CONFIGS[network].cpSwapProgram),
new web3_js_1.PublicKey(config_1.CONFIGS[network].cpSwapConfigAddress),
new web3_js_1.PublicKey(config_1.CONFIGS[network].createPoolFeeReceive),
];
// 2. Create LUT
const lookupTable = await (0, exports.createAddressLookupTable)(connection, payer, addresses);
// 3. Wait for LUT activation (must wait at least 1 slot)
await (0, sleep_promise_1.default)(1000);
return lookupTable;
};
exports.createLookupTable = createLookupTable;
//# sourceMappingURL=utils.js.map