import { PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js"; import type { PitProgram } from "../program.js"; import { getUserProfileAddress } from "../accounts/userProfile.js"; /** * Parameters for creating a set_nickname instruction */ export interface SetNicknameParams { /** User's wallet public key (signer) */ user: PublicKey; /** Custom nickname (max 32 UTF-8 **bytes**, empty string to reset) */ nickname: string; } /** * Create a set_nickname instruction * * This instruction allows users to set a custom on-chain nickname. * If the user profile doesn't exist, it will be created automatically. * * **IMPORTANT**: Nickname is validated by **byte length** (max 32 bytes), * not character count. Multi-byte UTF-8 characters (emoji, CJK) consume * 2-4 bytes each. * * @param program - Anchor Program instance * @param params - Nickname parameters * @returns Promise resolving to TransactionInstruction * * @example * ```typescript * import { createProgram, createSetNicknameInstruction } from "@pit-protocol/sdk"; * * const program = createProgram(provider); * const ix = await createSetNicknameInstruction(program, { * user: wallet.publicKey, * nickname: "Diamond Ape", * }); * * const tx = new Transaction().add(ix); * await sendAndConfirmTransaction(connection, tx, [wallet]); * ``` */ export async function createSetNicknameInstruction( program: PitProgram, params: SetNicknameParams ): Promise { const { user, nickname } = params; // Validate nickname byte length (client-side validation) const byteLength = Buffer.byteLength(nickname, "utf8"); if (byteLength > 32) { throw new Error( `Nickname too long: ${byteLength} bytes (max 32 bytes). ` + `Multi-byte characters (emoji, CJK) use 2-4 bytes each.` ); } const userProfile = getUserProfileAddress(user); return await program.methods .setNickname(nickname) .accountsPartial({ userProfile, user, systemProgram: SystemProgram.programId, }) .instruction(); }