well, a lot of stuff.
This commit is contained in:
parent
b6ac259413
commit
ff339ed482
|
@ -3,7 +3,7 @@ import * as fs from 'fs';
|
|||
import { program } from 'commander';
|
||||
import * as anchor from '@project-serum/anchor';
|
||||
import { LAMPORTS_PER_SOL } from '@solana/web3.js';
|
||||
|
||||
import { Token } from '@solana/spl-token';
|
||||
import { CACHE_PATH, TOKEN_PROGRAM_ID } from './helpers/constants';
|
||||
import {
|
||||
loadFairLaunchProgram,
|
||||
|
@ -11,7 +11,11 @@ import {
|
|||
getTokenMint,
|
||||
getFairLaunch,
|
||||
getTreasury,
|
||||
getFairLaunchTicket,
|
||||
getAtaForMint,
|
||||
getFairLaunchTicketSeqLookup,
|
||||
} from './helpers/accounts';
|
||||
import { sleep } from './helpers/various';
|
||||
program.version('0.0.1');
|
||||
|
||||
if (!fs.existsSync(CACHE_PATH)) {
|
||||
|
@ -145,6 +149,137 @@ program
|
|||
console.log(`create fair launch Done: ${fairLaunch.toBase58()}`);
|
||||
});
|
||||
|
||||
program
|
||||
.command('purchase_ticket')
|
||||
.option(
|
||||
'-e, --env <string>',
|
||||
'Solana cluster env name',
|
||||
'devnet', //mainnet-beta, testnet, devnet
|
||||
)
|
||||
.option(
|
||||
'-k, --keypair <path>',
|
||||
`Solana wallet location`,
|
||||
'--keypair not provided',
|
||||
)
|
||||
.option('-f, --fair-launch <string>', 'fair launch id')
|
||||
.option('-a, --amount <string>', 'amount')
|
||||
.action(async (_, cmd) => {
|
||||
const { env, keypair, fairLaunch, amount } = cmd.opts();
|
||||
let amountNumber = parseFloat(amount);
|
||||
|
||||
const walletKeyPair = loadWalletKey(keypair);
|
||||
const anchorProgram = await loadFairLaunchProgram(walletKeyPair, env);
|
||||
|
||||
const fairLaunchKey = new anchor.web3.PublicKey(fairLaunch);
|
||||
const fairLaunchObj = await anchorProgram.account.fairLaunch.fetch(
|
||||
fairLaunchKey,
|
||||
);
|
||||
const [fairLaunchTicket, bump] = await getFairLaunchTicket(
|
||||
//@ts-ignore
|
||||
fairLaunchObj.tokenMint,
|
||||
walletKeyPair.publicKey,
|
||||
);
|
||||
|
||||
const remainingAccounts = [];
|
||||
const instructions = [];
|
||||
const signers = [];
|
||||
|
||||
//@ts-ignore
|
||||
if (!fairLaunchObj.treasuryMint) {
|
||||
amountNumber = Math.ceil(amountNumber * LAMPORTS_PER_SOL);
|
||||
} else {
|
||||
const transferAuthority = anchor.web3.Keypair.generate();
|
||||
signers.push(transferAuthority);
|
||||
|
||||
instructions.push(
|
||||
Token.createApproveInstruction(
|
||||
TOKEN_PROGRAM_ID,
|
||||
//@ts-ignore
|
||||
fairLaunchObj.treasuryMint,
|
||||
transferAuthority.publicKey,
|
||||
walletKeyPair.publicKey,
|
||||
[],
|
||||
//@ts-ignore
|
||||
amountNumber + fairLaunchObj.data.fees.toNumber(),
|
||||
),
|
||||
);
|
||||
|
||||
remainingAccounts.push({
|
||||
//@ts-ignore
|
||||
pubkey: fairLaunchObj.treasuryMint,
|
||||
isWritable: true,
|
||||
isSigner: false,
|
||||
});
|
||||
remainingAccounts.push({
|
||||
pubkey: (
|
||||
await getAtaForMint(
|
||||
//@ts-ignore
|
||||
fairLaunchObj.treasuryMint,
|
||||
walletKeyPair.publicKey,
|
||||
)
|
||||
)[0],
|
||||
isWritable: true,
|
||||
isSigner: false,
|
||||
});
|
||||
remainingAccounts.push({
|
||||
pubkey: transferAuthority.publicKey,
|
||||
isWritable: false,
|
||||
isSigner: true,
|
||||
});
|
||||
remainingAccounts.push({
|
||||
pubkey: TOKEN_PROGRAM_ID,
|
||||
isWritable: false,
|
||||
isSigner: false,
|
||||
});
|
||||
}
|
||||
|
||||
await anchorProgram.rpc.purchaseTicket(bump, new anchor.BN(amountNumber), {
|
||||
accounts: {
|
||||
fairLaunchTicket,
|
||||
fairLaunch,
|
||||
//@ts-ignore
|
||||
treasury: fairLaunchObj.treasury,
|
||||
buyer: walletKeyPair.publicKey,
|
||||
payer: walletKeyPair.publicKey,
|
||||
systemProgram: anchor.web3.SystemProgram.programId,
|
||||
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||||
clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
|
||||
},
|
||||
//__private: { logAccounts: true },
|
||||
remainingAccounts,
|
||||
signers,
|
||||
instructions: instructions.length > 0 ? instructions : undefined,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`create fair launch ticket Done: ${fairLaunchTicket.toBase58()}. Trying to create seq now...we may or may not get a validator with data on chain. Either way, your ticket is secure.`,
|
||||
);
|
||||
|
||||
await sleep(5000);
|
||||
const fairLaunchTicketObj =
|
||||
await anchorProgram.account.fairLaunchTicket.fetch(fairLaunchTicket);
|
||||
|
||||
const [fairLaunchTicketSeqLookup, seqBump] =
|
||||
await getFairLaunchTicketSeqLookup(
|
||||
//@ts-ignore
|
||||
fairLaunchObj.tokenMint,
|
||||
//@ts-ignore
|
||||
fairLaunchTicketObj.seq,
|
||||
);
|
||||
|
||||
await anchorProgram.rpc.createTicketSeq(seqBump, {
|
||||
accounts: {
|
||||
fairLaunchTicketSeqLookup,
|
||||
fairLaunch,
|
||||
fairLaunchTicket,
|
||||
payer: walletKeyPair.publicKey,
|
||||
systemProgram: anchor.web3.SystemProgram.programId,
|
||||
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||||
},
|
||||
signers: [],
|
||||
});
|
||||
});
|
||||
|
||||
program
|
||||
.command('show')
|
||||
.option(
|
||||
|
@ -290,4 +425,51 @@ program
|
|||
);
|
||||
});
|
||||
|
||||
program
|
||||
.command('show_ticket')
|
||||
.option(
|
||||
'-e, --env <string>',
|
||||
'Solana cluster env name',
|
||||
'devnet', //mainnet-beta, testnet, devnet
|
||||
)
|
||||
.option(
|
||||
'-k, --keypair <path>',
|
||||
`Solana wallet location`,
|
||||
'--keypair not provided',
|
||||
)
|
||||
.option('-f, --fair-launch <string>', 'fair launch id')
|
||||
.action(async (options, cmd) => {
|
||||
const { env, fairLaunch, keypair } = cmd.opts();
|
||||
|
||||
const walletKeyPair = loadWalletKey(keypair);
|
||||
const anchorProgram = await loadFairLaunchProgram(walletKeyPair, env);
|
||||
|
||||
const fairLaunchObj = await anchorProgram.account.fairLaunch.fetch(
|
||||
fairLaunch,
|
||||
);
|
||||
|
||||
const fairLaunchTicket = (
|
||||
await getFairLaunchTicket(
|
||||
//@ts-ignore
|
||||
fairLaunchObj.tokenMint,
|
||||
walletKeyPair.publicKey,
|
||||
)
|
||||
)[0];
|
||||
|
||||
const fairLaunchTicketObj =
|
||||
await anchorProgram.account.fairLaunchTicket.fetch(fairLaunchTicket);
|
||||
|
||||
//@ts-ignore
|
||||
console.log('Buyer', fairLaunchTicketObj.buyer.toBase58());
|
||||
//@ts-ignore
|
||||
console.log('Fair Launch', fairLaunchTicketObj.fairLaunch.toBase58());
|
||||
//@ts-ignore
|
||||
console.log('Current Amount', fairLaunchTicketObj.amount.toNumber());
|
||||
//@ts-ignore
|
||||
console.log('State', fairLaunchTicketObj.state);
|
||||
//@ts-ignore
|
||||
console.log('Bump', fairLaunchTicketObj.bump);
|
||||
//@ts-ignore
|
||||
console.log('Sequence', fairLaunchTicketObj.seq.toNumber());
|
||||
});
|
||||
program.parse(process.argv);
|
||||
|
|
|
@ -118,6 +118,36 @@ export const getFairLaunch = async (
|
|||
);
|
||||
};
|
||||
|
||||
export const getFairLaunchTicket = async (
|
||||
tokenMint: anchor.web3.PublicKey,
|
||||
buyer: anchor.web3.PublicKey,
|
||||
): Promise<[anchor.web3.PublicKey, number]> => {
|
||||
return await anchor.web3.PublicKey.findProgramAddress(
|
||||
[Buffer.from('fair_launch'), tokenMint.toBuffer(), buyer.toBuffer()],
|
||||
FAIR_LAUNCH_PROGRAM_ID,
|
||||
);
|
||||
};
|
||||
|
||||
export const getFairLaunchTicketSeqLookup = async (
|
||||
tokenMint: anchor.web3.PublicKey,
|
||||
seq: anchor.BN,
|
||||
): Promise<[anchor.web3.PublicKey, number]> => {
|
||||
return await anchor.web3.PublicKey.findProgramAddress(
|
||||
[Buffer.from('fair_launch'), tokenMint.toBuffer(), seq.toBuffer()],
|
||||
FAIR_LAUNCH_PROGRAM_ID,
|
||||
);
|
||||
};
|
||||
|
||||
export const getAtaForMint = async (
|
||||
mint: anchor.web3.PublicKey,
|
||||
buyer: anchor.web3.PublicKey,
|
||||
): Promise<[anchor.web3.PublicKey, number]> => {
|
||||
return await anchor.web3.PublicKey.findProgramAddress(
|
||||
[buyer.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()],
|
||||
SPL_ASSOCIATED_TOKEN_ACCOUNT_PROGRAM_ID,
|
||||
);
|
||||
};
|
||||
|
||||
export const getTreasury = async (
|
||||
tokenMint: anchor.web3.PublicKey,
|
||||
): Promise<[anchor.web3.PublicKey, number]> => {
|
||||
|
|
|
@ -799,13 +799,13 @@ pub struct UpdateFairLaunchLotteryBitmap<'info> {
|
|||
#[derive(Accounts)]
|
||||
#[instruction(bump: u8, amount: u64)]
|
||||
pub struct PurchaseTicket<'info> {
|
||||
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), buyer.key.as_ref()], payer=payer, bump=bump, space=FAIR_LAUNCH_TICKET_SIZE)]
|
||||
fair_launch_ticket: ProgramAccount<'info, FairLaunchTicket>,
|
||||
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref()], bump=fair_launch.bump, has_one=treasury)]
|
||||
fair_launch: ProgramAccount<'info, FairLaunch>,
|
||||
#[account(mut)]
|
||||
treasury: AccountInfo<'info>,
|
||||
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), buyer.key.as_ref()], payer=payer, bump=bump, space=FAIR_LAUNCH_TICKET_SIZE)]
|
||||
fair_launch_ticket: ProgramAccount<'info, FairLaunchTicket>,
|
||||
#[account(mut, signer, constraint= (treasury.owner == &spl_token::id() && buyer.owner == &spl_token::id()) || (treasury.owner != &spl_token::id() && buyer.data_is_empty() && buyer.lamports() > 0) )]
|
||||
#[account(mut, signer, constraint= buyer.data_is_empty() && buyer.lamports() > 0)]
|
||||
buyer: AccountInfo<'info>,
|
||||
#[account(mut, signer)]
|
||||
payer: AccountInfo<'info>,
|
||||
|
@ -824,12 +824,12 @@ pub struct PurchaseTicket<'info> {
|
|||
#[derive(Accounts)]
|
||||
#[instruction(bump: u8)]
|
||||
pub struct CreateTicketSeq<'info> {
|
||||
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &fair_launch_ticket.seq.to_le_bytes()], payer=payer, bump=bump, space=FAIR_LAUNCH_TICKET_SEQ_SIZE)]
|
||||
fair_launch_ticket_seq_lookup: ProgramAccount<'info, FairLaunchTicketSeqLookup>,
|
||||
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref()], bump=fair_launch.bump)]
|
||||
fair_launch: ProgramAccount<'info, FairLaunch>,
|
||||
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), fair_launch_ticket.buyer.as_ref()], bump=fair_launch_ticket.bump, has_one=fair_launch)]
|
||||
fair_launch_ticket: ProgramAccount<'info, FairLaunchTicket>,
|
||||
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &fair_launch_ticket.seq.to_le_bytes()], payer=payer, bump=bump, space=FAIR_LAUNCH_TICKET_SEQ_SIZE)]
|
||||
fair_launch_ticket_seq_lookup: ProgramAccount<'info, FairLaunchTicketSeqLookup>,
|
||||
#[account(mut, signer)]
|
||||
payer: AccountInfo<'info>,
|
||||
#[account(address = system_program::ID)]
|
||||
|
|
|
@ -209,8 +209,10 @@ pub fn assert_valid_amount(data: &FairLaunchData, amount: u64) -> ProgramResult
|
|||
return Err(ErrorCode::InvalidPurchaseAmount.into());
|
||||
}
|
||||
|
||||
if amount.checked_rem(data.tick_size).is_some() {
|
||||
return Err(ErrorCode::InvalidPurchaseAmount.into());
|
||||
if let Some(val) = amount.checked_rem(data.tick_size) {
|
||||
if val > 0 {
|
||||
return Err(ErrorCode::InvalidPurchaseAmount.into());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -299,4 +301,4 @@ pub fn spl_token_mint_to<'a: 'b, 'b>(
|
|||
&[authority_signer_seeds],
|
||||
);
|
||||
result.map_err(|_| ErrorCode::TokenMintToFailed.into())
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue