123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import { start } from 'solana-bankrun';
- import { expect } from 'chai';
- import { PublicKey, SystemProgram, Keypair, Connection } from '@solana/web3.js';
- import { TOKEN_PROGRAM_ID, createMint, getOrCreateAssociatedTokenAccount, mintTo } from '@solana/spl-token';
- jest.setTimeout(30000); // Set timeout to 30 seconds
- const ACCOUNT_SIZE = 8 + 32 + 20; // Define your account size here
- async function retryWithBackoff(fn: () => Promise<any>, retries = 5, delay = 500): Promise<any> {
- try {
- return await fn();
- } catch (err) {
- if (retries === 0) throw err;
- await new Promise(resolve => setTimeout(resolve, delay));
- return retryWithBackoff(fn, retries - 1, delay * 2);
- }
- }
- describe('External Delegate Token Master Tests', () => {
- let context: any;
- let program: any;
- let authority: Keypair;
- let userAccount: Keypair;
- let mint: PublicKey;
- let userTokenAccount: PublicKey;
- let recipientTokenAccount: PublicKey;
- let userPda: PublicKey;
- let bumpSeed: number;
- beforeEach(async () => {
- authority = Keypair.generate();
- userAccount = Keypair.generate();
- const programs = [
- {
- name: "external_delegate_token_master",
- programId: new PublicKey("FYPkt5VWMvtyWZDMGCwoKFkE3wXTzphicTpnNGuHWVbD"),
- program: "target/deploy/external_delegate_token_master.so",
- },
- ];
- context = await retryWithBackoff(async () => await start(programs, []));
- const connection = new Connection("https://api.devnet.solana.com", "confirmed");
- context.connection = connection;
- // Airdrop SOL to authority with retry logic
- await retryWithBackoff(async () => {
- await connection.requestAirdrop(authority.publicKey, 1000000000);
- });
- // Create mint with retry logic
- mint = await retryWithBackoff(async () =>
- await createMint(connection, authority, authority.publicKey, null, 6)
- );
- const userTokenAccountInfo = await retryWithBackoff(async () =>
- await getOrCreateAssociatedTokenAccount(connection, authority, mint, authority.publicKey)
- );
- userTokenAccount = userTokenAccountInfo.address;
- const recipientTokenAccountInfo = await retryWithBackoff(async () =>
- await getOrCreateAssociatedTokenAccount(connection, authority, mint, Keypair.generate().publicKey)
- );
- recipientTokenAccount = recipientTokenAccountInfo.address;
- // Mint tokens to the user's account
- await retryWithBackoff(async () =>
- await mintTo(connection, authority, mint, userTokenAccount, authority, 1000000000)
- );
- // Find program-derived address (PDA)
- [userPda, bumpSeed] = await retryWithBackoff(async () =>
- await PublicKey.findProgramAddress([userAccount.publicKey.toBuffer()], context.program.programId)
- );
- });
- it('should initialize user account', async () => {
- const space = ACCOUNT_SIZE;
- const rentExempt = await retryWithBackoff(async () => {
- return await context.connection.getMinimumBalanceForRentExemption(space);
- });
- await context.program.methods
- .initialize()
- .accounts({
- userAccount: userAccount.publicKey,
- authority: authority.publicKey,
- systemProgram: SystemProgram.programId,
- })
- .preInstructions([
- SystemProgram.createAccount({
- fromPubkey: authority.publicKey,
- newAccountPubkey: userAccount.publicKey,
- lamports: rentExempt,
- space: space,
- programId: context.program.programId,
- }),
- ])
- .signers([authority, userAccount])
- .rpc();
- const account = await context.program.account.userAccount.fetch(userAccount.publicKey);
- expect(account.authority.toString()).to.equal(authority.publicKey.toString());
- expect(account.ethereumAddress).to.deep.equal(new Array(20).fill(0));
- });
- it('should set ethereum address', async () => {
- const ethereumAddress = Buffer.from('1C8cd0c38F8DE35d6056c7C7aBFa7e65D260E816', 'hex');
- await context.program.methods
- .setEthereumAddress(ethereumAddress)
- .accounts({
- userAccount: userAccount.publicKey,
- authority: authority.publicKey,
- })
- .signers([authority])
- .rpc();
- const account = await context.program.account.userAccount.fetch(userAccount.publicKey);
- expect(account.ethereumAddress).to.deep.equal(Array.from(ethereumAddress));
- });
- it('should perform authority transfer', async () => {
- const newAuthority = Keypair.generate();
- await context.program.methods
- .transferAuthority(newAuthority.publicKey)
- .accounts({
- userAccount: userAccount.publicKey,
- authority: authority.publicKey,
- })
- .signers([authority])
- .rpc();
- const account = await context.program.account.userAccount.fetch(userAccount.publicKey);
- expect(account.authority.toString()).to.equal(newAuthority.publicKey.toString());
- });
- afterEach(async () => {
- if (context && typeof context.terminate === 'function') {
- await context.terminate();
- }
- });
- });
|