import {
  Connection,
  PublicKey,
  SystemProgram,
  Transaction,
} from "@solana/web3.js";
import { CdpClient } from "@coinbase/cdp-sdk";
import dotenv from "dotenv";
dotenv.config();
const cdp = new CdpClient();
const connection = new Connection("https://api.devnet.solana.com");
async function createAccount() {
  const account = await cdp.solana.createAccount();
  console.log(`Created account: ${account.address}`);
  return account;
}
async function requestFaucet(address: string) {
  await cdp.solana.requestFaucet({
    address,
    token: "sol",
  });
}
async function waitForBalance(address: string) {
  let balance = 0;
  let attempts = 0;
  const maxAttempts = 30;
  while (balance === 0 && attempts < maxAttempts) {
    balance = await connection.getBalance(new PublicKey(address));
    if (balance === 0) {
      console.log("Waiting for funds...");
      await new Promise(resolve => setTimeout(resolve, 1000));
      attempts++;
    } else {
      console.log("Account funded with", balance / 1e9, "SOL");
    }
  }
  if (balance === 0) {
    throw new Error("Account not funded after multiple attempts");
  }
}
async function sendTransaction(address: string) {
  // Amount of lamports to send (default: 1000 = 0.000001 SOL)
  const lamportsToSend = 1000;
  const fromAddress = new PublicKey(address)
  const destinations = [
    "ANVUJaJoVaJZELtV2AvRp7V5qPV1B84o29zAwDhPj1c2",
    "EeVPcnRE1mhcY85wAh3uPJG1uFiTNya9dCJjNUPABXzo",
    "4PkiqJkUvxr9P8C1UsMqGN8NJsUcep9GahDRLfmeu8UK",
  ]
  const { blockhash } = await connection.getLatestBlockhash();
  // Create instructions for each destination
  const instructions = destinations.map((toAddress) => {
    return SystemProgram.transfer({
      fromPubkey: fromAddress,
      toPubkey: new PublicKey(toAddress),
      lamports: lamportsToSend,
    })
  })
  // Create a single transaction with all instructions
  const transaction = new Transaction();
  transaction.add(...instructions);
  transaction.recentBlockhash = blockhash;
  transaction.feePayer = fromAddress;
  const serializedTx = Buffer.from(
    transaction.serialize({ requireAllSignatures: false })
  ).toString("base64");
  const { signature: txSignature } = await cdp.solana.signTransaction({
    address,
    transaction: serializedTx,
  });
  const decodedSignedTx = Buffer.from(txSignature, "base64");
  console.log("Sending transaction...");
  const txSendSignature = await connection.sendRawTransaction(decodedSignedTx);
  const latestBlockhash = await connection.getLatestBlockhash();
  console.log("Waiting for transaction to be confirmed...");
  const confirmation = await connection.confirmTransaction({
    signature: txSendSignature,
    blockhash: latestBlockhash.blockhash,
    lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
  });
  if (confirmation.value.err) {
    throw new Error(`Transaction failed: ${confirmation.value.err.toString()}`);
  }
  console.log(`Sent SOL: https://explorer.solana.com/tx/${txSendSignature}?cluster=devnet`);
}
async function main() {
  const account = await createAccount();
  await requestFaucet(account.address);
  await waitForBalance(account.address);
  await sendTransaction(account.address);
}
main().catch(console.error)