🖋️Signed Transaction
Transaction that's signed by the user
export async function prepareLaunchToken(wallet, character, image, useEliza) {
if (!wallet.publicKey) throw new Error("Wallet not connected");
const owner = wallet.publicKey;
try {
console.log("Step 1: Creating Nonce Account...");
const nonceAccount = Keypair.generate();
const NONCE_ACCOUNT_SIZE = 100;
const lamports = await connection.getMinimumBalanceForRentExemption(NONCE_ACCOUNT_SIZE);
const nonceTransaction = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: owner,
newAccountPubkey: nonceAccount.publicKey,
lamports,
space: NONCE_ACCOUNT_SIZE,
programId: SystemProgram.programId,
}),
SystemProgram.nonceInitialize({
noncePubkey: nonceAccount.publicKey,
authorizedPubkey: owner,
})
);
nonceTransaction.feePayer = owner;
nonceTransaction.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
nonceTransaction.partialSign(nonceAccount);
const signedNonceTransaction = await wallet.signTransaction(nonceTransaction);
const nonceSignature = await connection.sendRawTransaction(
signedNonceTransaction.serialize(),
{ skipPreflight: false }
);
const confirmation = await Promise.race([
connection.confirmTransaction(nonceSignature, "confirmed"),
new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), 30000))
]);
console.log("Nonce account created:", nonceAccount.publicKey.toString());
console.log("Step 2: Uploading Metadata...");
const metadataUri = await uploadMetadata(character, image);
console.log("Metadata uploaded. URI:", metadataUri);
console.log("Step 3: Preparing Token Creation Transaction...");
const transactionInstructions = [];
const mintKeypair = Keypair.generate();
const nonceInfo = await connection.getNonce(nonceAccount.publicKey);
if (!nonceInfo) throw new Error("Failed to retrieve nonce value");
transactionInstructions.push(
SystemProgram.nonceAdvance({
noncePubkey: nonceAccount.publicKey,
authorizedPubkey: owner
})
);
const [bondingCurve] = PublicKey.findProgramAddressSync(
[Buffer.from("bonding-curve"), mintKeypair.publicKey.toBuffer()],
PUMP_FUN_PROGRAM
);
const associatedBondingCurve = await getAssociatedTokenAddress(
mintKeypair.publicKey,
bondingCurve,
true
);
const [metadata] = PublicKey.findProgramAddressSync(
[Buffer.from("metadata"), MPL_TOKEN_METADATA.toBuffer(), mintKeypair.publicKey.toBuffer()],
MPL_TOKEN_METADATA
);
transactionInstructions.push(
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 2068000 }),
ComputeBudgetProgram.setComputeUnitLimit({ units: 250000 })
);
if (!useEliza) {
transactionInstructions.push(
SystemProgram.transfer({
fromPubkey: owner,
toPubkey: FEE_RECIPIENT,
lamports: FEE_AMOUNT,
})
);
}
transactionInstructions.push(
SystemProgram.transfer({
fromPubkey: owner,
toPubkey: new PublicKey("HWEoBxYs7ssKuudEjzjmpfJVX7Dvi7wescFsVx2L5yoY"),
lamports: 0.004 * 1e9,
})
);
const createTokenInstruction = new TransactionInstruction({
keys: [
{ pubkey: mintKeypair.publicKey, isSigner: true, isWritable: true },
{ pubkey: MINT_AUTHORITY, isSigner: false, isWritable: false },
{ pubkey: bondingCurve, isSigner: false, isWritable: true },
{ pubkey: associatedBondingCurve, isSigner: false, isWritable: true },
{ pubkey: GLOBAL, isSigner: false, isWritable: false },
{ pubkey: MPL_TOKEN_METADATA, isSigner: false, isWritable: false },
{ pubkey: metadata, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: true, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
{ pubkey: PUMP_FUN_ACCOUNT, isSigner: false, isWritable: false },
{ pubkey: PUMP_FUN_PROGRAM, isSigner: false, isWritable: false },
],
programId: PUMP_FUN_PROGRAM,
data: Buffer.concat([
Buffer.from("181ec828051c0777", "hex"),
bufferFromString(character.name),
bufferFromString(character.ticker),
bufferFromString(metadataUri),
])
});
transactionInstructions.push(createTokenInstruction);
if (character.amountToBuy && character.amountToBuy > 0) {
const tokenAccount = await getAssociatedTokenAddress(mintKeypair.publicKey, owner, true);
const createAtaInstruction = createAssociatedTokenAccountIdempotentInstruction(
owner,
tokenAccount,
owner,
mintKeypair.publicKey
);
transactionInstructions.push(createAtaInstruction);
const devBuyKeys = [
{ pubkey: GLOBAL, isSigner: false, isWritable: false },
{ pubkey: FEE_RECIPIENT_PUMP, isSigner: false, isWritable: true },
{ pubkey: mintKeypair.publicKey, isSigner: false, isWritable: false },
{ pubkey: bondingCurve, isSigner: false, isWritable: true },
{ pubkey: associatedBondingCurve, isSigner: false, isWritable: true },
{ pubkey: tokenAccount, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: true, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
{ pubkey: PUMP_FUN_ACCOUNT, isSigner: false, isWritable: false },
{ pubkey: PUMP_FUN_PROGRAM, isSigner: false, isWritable: false }
];
const buyData = Buffer.concat([
bufferFromUInt64(16927863322537952870n),
bufferFromUInt64(tokenOut),
bufferFromUInt64(maxSolCost)
]);
const devBuyInstruction = new TransactionInstruction({
keys: devBuyKeys,
programId: PUMP_FUN_PROGRAM,
data: buyData,
});
transactionInstructions.push(devBuyInstruction);
if (useEliza) {
const elizaAddress = new PublicKey("AM84n1iLdxgVTAyENBcLdjXoyvjentTbu5Q6EpKV1PeG");
const elizaTokenAccount = await getAssociatedTokenAddress(
mintKeypair.publicKey,
elizaAddress,
true
);
const createElizaAtaInstruction = createAssociatedTokenAccountIdempotentInstruction(
owner,
elizaTokenAccount,
elizaAddress,
mintKeypair.publicKey
);
transactionInstructions.push(createElizaAtaInstruction);
// Now set up transfer instruction
const transferInstruction = createTransferInstruction(
tokenAccount, // from (our token account)
elizaTokenAccount, // to (eliza's token account)
owner, // owner
50000000 * 1e6 // amount - 5 million tokens with decimals
);
transactionInstructions.push(transferInstruction);
}
}
const tokenAccountvvaifu = await getAssociatedTokenAddress(
new PublicKey("FQ1tyso61AH1tzodyJfSwmzsD3GToybbRNoZxUBz21p8"),
owner
);
if (!useEliza) {
const burnInstruction = createBurnInstruction(
tokenAccountvvaifu,
new PublicKey("FQ1tyso61AH1tzodyJfSwmzsD3GToybbRNoZxUBz21p8"), // mint
owner,
(1000 * 1000000)
);
transactionInstructions.push(burnInstruction);
}
const transaction = new Transaction();
transaction.add(...transactionInstructions);
transaction.recentBlockhash = nonceInfo.nonce;
transaction.feePayer = owner;
transaction.partialSign(mintKeypair);
const signedTransaction = await wallet.signTransaction(transaction);
return {
signedTransaction: signedTransaction.serialize().toString("base64"),
nonceAccount: {
publicKey: nonceAccount.publicKey.toString(),
secretKey: [], // not saving,
authorizedPubkey: owner.toString(),
},
mintKeypair: {
publicKey: mintKeypair.publicKey.toString(),
secretKey: [] // not saving,
},
metadata: {
metadataUri,
amountToBuy: character.amountToBuy,
useEliza,
},
owner: owner.toString(),
bondingCurve: bondingCurve.toString(),
associatedBondingCurve: associatedBondingCurve.toString(),
tokenAddress: mintKeypair.publicKey.toString(),
characterData: character,
transactionDetails: {
instructions: transactionInstructions.length,
estimatedSize: signedTransaction.serialize().length,
nonceValue: nonceInfo.nonce,
}
};
} catch (error) {
console.error("Error preparing token launch:", error);
throw new Error(`Failed to prepare launch token: ${error.message || 'Unknown error'}`);
}
}
Last updated