@kamino-finance/farms-sdk
Version:
174 lines (160 loc) • 4.29 kB
text/typescript
import {
createMintToInstruction,
getAssociatedTokenAddressSync,
TOKEN_PROGRAM_ID,
unpackMint,
} from "@solana/spl-token";
import {
Connection,
Keypair,
PublicKey,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
import {
createInitializeMint2Instruction,
createAssociatedTokenAccountIdempotentInstruction as createAta,
getAssociatedTokenAddress as getAta,
} from "@solana/spl-token";
import * as anchor from "@coral-xyz/anchor";
import { createAddExtraComputeUnitFeeTransaction } from "../commands/utils";
import { checkIfAccountExists } from "./utils";
export async function createMint(
provider: anchor.AnchorProvider,
authority: PublicKey,
decimals: number = 6,
): Promise<PublicKey> {
const mint = anchor.web3.Keypair.generate();
return await createMintFromKeypair(provider, authority, mint, decimals);
}
export async function createMintFromKeypair(
provider: anchor.AnchorProvider,
authority: PublicKey,
mint: Keypair,
decimals: number = 6,
): Promise<PublicKey> {
const instructions = await createMintInstructions(
provider,
authority,
mint.publicKey,
decimals,
);
const tx = new anchor.web3.Transaction();
tx.add(...instructions);
await provider.sendAndConfirm(tx, [mint]);
return mint.publicKey;
}
async function createMintInstructions(
provider: anchor.AnchorProvider,
authority: PublicKey,
mint: PublicKey,
decimals: number,
): Promise<TransactionInstruction[]> {
return [
anchor.web3.SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: mint,
space: 82,
lamports: await provider.connection.getMinimumBalanceForRentExemption(82),
programId: TOKEN_PROGRAM_ID,
}),
createInitializeMint2Instruction(
mint,
decimals,
authority,
null,
TOKEN_PROGRAM_ID,
),
];
}
export async function getMintDecimals(
connection: Connection,
mintAddress: PublicKey,
): Promise<number> {
const acc = await connection.getAccountInfo(mintAddress);
if (!acc) {
throw new Error(`Failed to find mint account ${mintAddress.toBase58()}`);
}
return unpackMint(mintAddress, acc, acc.owner).decimals;
}
export function getAssociatedTokenAddress(
owner: PublicKey,
tokenMintAddress: PublicKey,
tokenProgram: PublicKey,
): PublicKey {
return getAssociatedTokenAddressSync(
tokenMintAddress,
owner,
true,
tokenProgram,
);
}
export async function createAssociatedTokenAccountIdempotentInstruction(
owner: PublicKey,
mint: PublicKey,
payer: PublicKey = owner,
tokenProgram: PublicKey,
ata?: PublicKey,
): Promise<[PublicKey, TransactionInstruction]> {
let ataAddress = ata;
if (!ataAddress) {
ataAddress = await getAssociatedTokenAddress(owner, mint, tokenProgram);
}
const createUserTokenAccountIx = createAta(
payer,
ataAddress,
owner,
mint,
tokenProgram,
);
return [ataAddress, createUserTokenAccountIx];
}
export async function setupAta(
provider: anchor.AnchorProvider,
tokenMintAddress: PublicKey,
user: Keypair,
): Promise<PublicKey> {
const ata = await getAssociatedTokenAddress(
user.publicKey,
tokenMintAddress,
TOKEN_PROGRAM_ID,
);
if (!(await checkIfAccountExists(provider.connection, ata))) {
const [, ix] = await createAssociatedTokenAccountIdempotentInstruction(
user.publicKey,
tokenMintAddress,
user.publicKey,
TOKEN_PROGRAM_ID,
ata,
);
const tx = new Transaction().add(ix);
await provider.connection.sendTransaction(tx, [user]);
}
return ata;
}
export async function mintTo(
provider: anchor.AnchorProvider,
mintPubkey: PublicKey,
tokenAccount: PublicKey,
amount: number,
) {
const tx = new Transaction().add(
createMintToInstruction(
mintPubkey,
tokenAccount,
provider.wallet.publicKey,
amount,
[],
TOKEN_PROGRAM_ID,
),
);
const microLamport = 10 ** 6; // 1 lamport
const computeUnits = 200_000;
const microLamportsPrioritizationFee = microLamport / computeUnits;
const priorityFeeIxn = createAddExtraComputeUnitFeeTransaction(
computeUnits,
microLamportsPrioritizationFee * 5,
);
tx.add(...priorityFeeIxn);
await provider.sendAndConfirm(tx);
}