@blockassetlabs/blaze
Version:
Blockasset Blaze
290 lines (273 loc) • 7.48 kB
text/typescript
import { BN } from '@project-serum/anchor';
import type { Wallet } from '@saberhq/solana-contrib';
import type {
AccountMeta,
Connection,
PublicKey,
Transaction
} from '@solana/web3.js';
import { Keypair, SystemProgram } from '@solana/web3.js';
import { tryGetAccount } from '../../utils/tryGetAccount';
import { withFindOrInitAssociatedTokenAccount } from '../../utils/withFindOrInitAssociatedTokenAccount';
import { getIdentifier } from './accounts';
import { BLAZE_ADDRESS } from './constants';
import {
claimPrizeInstruction,
closeBlazeInstruction,
initBlazeInstruction,
initIdentifierInstruction,
redeemEntrantsInstruction,
resolveBlazeInstruction,
updateBlazeInstruction
} from './instruction';
import { findBlazeId, findIdentifierId } from './pda';
/**
* Add init blaze identifier instructions to a transaction
* @param transaction
* @param connection
* @param wallet
* @returns Transaction, public key for the created blaze identifier
*/
export const withInitBlazeIdentifier = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet
): Promise<[Transaction, PublicKey]> => {
const [identifierId] = await findIdentifierId();
transaction.add(
await initIdentifierInstruction(connection, wallet, {
identifierId: identifierId
})
);
return [transaction, identifierId];
};
export const withInitBlaze = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet,
params: {
prizeMint: PublicKey;
tokenMint?: PublicKey;
tokenAccount?: PublicKey;
treasury?: PublicKey;
burnRate?: number;
entrantFee: BN;
maxEntrants: number;
start: BN;
end: BN;
maxEntrantsPerWalletRate?: number;
projectId: PublicKey;
projectWallet: PublicKey;
category?: string;
}
): Promise<[Transaction, PublicKey, Keypair]> => {
const [[identifierId], identifierData] = await Promise.all([
findIdentifierId(),
tryGetAccount(() => getIdentifier(connection))
]);
const identifier = (identifierData?.parsed.count as BN) || new BN(1);
if (!identifierData) {
transaction.add(
await initIdentifierInstruction(connection, wallet, {
identifierId: identifierId
})
);
}
const [blazeId] = await findBlazeId(identifier);
const [blazePrizeMintTokenAccount, userPrizeMintTokenAccount] =
await Promise.all([
withFindOrInitAssociatedTokenAccount(
transaction,
connection,
params.prizeMint,
blazeId,
wallet.publicKey,
true
),
withFindOrInitAssociatedTokenAccount(
transaction,
connection,
params.prizeMint,
wallet.publicKey,
wallet.publicKey
)
]);
const entrantsAccountDataSize = 8 + 4 + 4 + 32 * params.maxEntrants;
const entrantsKeyPair = Keypair.generate();
const lamports = await connection.getMinimumBalanceForRentExemption(
entrantsAccountDataSize,
'confirmed'
);
transaction.add(
SystemProgram.createAccount({
fromPubkey: wallet.publicKey,
newAccountPubkey: entrantsKeyPair.publicKey,
space: entrantsAccountDataSize,
lamports,
programId: BLAZE_ADDRESS
}),
await initBlazeInstruction(connection, wallet, {
identifierId,
blazeId,
projectId: params.projectId,
projectWallet: params.projectWallet,
blazePrizeMintTokenAccount,
userPrizeMintTokenAccount,
entrants: entrantsKeyPair.publicKey,
tokenMint: params.tokenMint,
tokenAccount: params.tokenAccount,
treasury: params.treasury,
burnRate: params.burnRate,
category: params.category,
prizeMint: params.prizeMint,
entrantFee: params.entrantFee,
maxEntrants: params.maxEntrants,
start: params.start,
end: params.end,
maxEntrantsPerWalletRate: params.maxEntrantsPerWalletRate
})
);
return [transaction, blazeId, entrantsKeyPair];
};
export const withUpdateBlaze = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet,
params: {
blazeId: PublicKey;
projectId: PublicKey;
tokenMint?: PublicKey;
tokenAccount?: PublicKey;
treasury?: PublicKey;
burnRate?: number;
entrantFee: BN;
start: BN;
end: BN;
maxEntrantsPerWalletRate?: number;
category?: string;
}
): Promise<Transaction> => {
transaction.add(
await updateBlazeInstruction(connection, wallet, {
blazeId: params.blazeId,
projectId: params.projectId,
tokenMint: params.tokenMint,
tokenAccount: params.tokenAccount,
treasury: params.treasury,
burnRate: params.burnRate,
entrantFee: params.entrantFee,
start: params.start,
end: params.end,
maxEntrantsPerWalletRate: params.maxEntrantsPerWalletRate,
category: params.category
})
);
return transaction;
};
export const withCloseBlaze = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet,
params: {
blazeId: PublicKey;
projectId: PublicKey;
prizeMint: PublicKey;
entrants: PublicKey;
}
): Promise<Transaction> => {
const [blazePrizeMintTokenAccount, userPrizeMintTokenAccount] =
await Promise.all([
withFindOrInitAssociatedTokenAccount(
transaction,
connection,
params.prizeMint,
params.blazeId,
wallet.publicKey,
true
),
withFindOrInitAssociatedTokenAccount(
transaction,
connection,
params.prizeMint,
wallet.publicKey,
wallet.publicKey
)
]);
transaction.add(
await closeBlazeInstruction(connection, wallet, {
blazeId: params.blazeId,
projectId: params.projectId,
entrants: params.entrants,
blazePrizeMintTokenAccount,
userPrizeMintTokenAccount
})
);
return transaction;
};
export const withRedeemEntrants = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet,
params: {
quantity: number;
blazeId: PublicKey;
entrants: PublicKey;
remainingAccountsForRedeem: AccountMeta[];
}
): Promise<Transaction> => {
transaction.add(await redeemEntrantsInstruction(connection, wallet, params));
return transaction;
};
export const withResolveBlaze = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet,
params: {
blazeId: PublicKey;
entrants: PublicKey;
}
): Promise<Transaction> => {
transaction.add(
await resolveBlazeInstruction(connection, wallet, {
blazeId: params.blazeId,
entrants: params.entrants
})
);
return transaction;
};
export const withClaimPrize = async (
transaction: Transaction,
connection: Connection,
wallet: Wallet,
params: {
blazeId: PublicKey;
prizeMint: PublicKey;
}
): Promise<Transaction> => {
const [blazePrizeMintTokenAccount, winnerPrizeMintTokenAccount] =
await Promise.all([
withFindOrInitAssociatedTokenAccount(
transaction,
connection,
params.prizeMint,
params.blazeId,
wallet.publicKey,
true
),
withFindOrInitAssociatedTokenAccount(
transaction,
connection,
params.prizeMint,
wallet.publicKey,
wallet.publicKey
)
]);
transaction.add(
await claimPrizeInstruction(connection, wallet, {
blazeId: params.blazeId,
blazePrizeMintTokenAccount,
winnerPrizeMintTokenAccount
})
);
return transaction;
};