// One-off Tempo USDC transfer.
//
// Fill in the CONFIG block below, then run:
//   /tmp/tempo-transfer/node_modules/.bin/tsx scripts/tempo-transfer.ts
//
// (The repo's node_modules has a @noble/hashes version conflict that breaks
// viem here, so the script runs from an isolated install at /tmp/tempo-transfer.
// To rebuild that dir if it disappears:
//   mkdir -p /tmp/tempo-transfer && cd /tmp/tempo-transfer \
//     && npm init -y && npm install viem@2.47.6 tsx)

// ─── CONFIG ──────────────────────────────────────────────────────────────────

const FROM = {
  privateKey: '82b62a625382eef1007a77d6eb3d848a9d1df0c9b59d2bd578893962003c17e2',
  wallet:     '0x084A80e395FaE8Aaf58F591f47F63DA1EeF06bbC',
};

const TO = {
  privateKey: '0x0a5194196773b67790f0da564337929b842c1c17f9c445b6c449205dbd426a49',
  wallet:     '0xc65d8a0dB80f637337B87e42b8BEb5D86D46f942',
};

const AMOUNT_USD = '1';

// ─────────────────────────────────────────────────────────────────────────────

import {
  createPublicClient,
  createWalletClient,
  http,
  formatUnits,
  parseUnits,
} from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { tempo } from 'viem/chains';

const USDC = '0x20c000000000000000000000b9537d11c60e8b50' as const;
const DECIMALS = 6;
const RPC = 'https://rpc.tempo.xyz';

const erc20Abi = [
  {
    name: 'balanceOf',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: 'account', type: 'address' }],
    outputs: [{ name: '', type: 'uint256' }],
  },
  {
    name: 'transfer',
    type: 'function',
    stateMutability: 'nonpayable',
    inputs: [
      { name: 'to', type: 'address' },
      { name: 'amount', type: 'uint256' },
    ],
    outputs: [{ name: '', type: 'bool' }],
  },
] as const;

function normalizePk(pk: string): `0x${string}` {
  const trimmed = pk.trim();
  return (trimmed.startsWith('0x') ? trimmed : `0x${trimmed}`) as `0x${string}`;
}

async function main() {
  const account = privateKeyToAccount(normalizePk(FROM.privateKey));
  const to = TO.wallet as `0x${string}`;
  const amount = parseUnits(AMOUNT_USD, DECIMALS);

  if (account.address.toLowerCase() !== FROM.wallet.toLowerCase()) {
    console.error(`FROM.privateKey derives ${account.address}, but FROM.wallet is ${FROM.wallet}`);
    process.exit(1);
  }

  const publicClient = createPublicClient({ chain: tempo, transport: http(RPC) });
  const walletClient = createWalletClient({ account, chain: tempo, transport: http(RPC) });

  console.log(`From:   ${account.address}`);
  console.log(`To:     ${to}`);
  console.log(`Amount: ${AMOUNT_USD} USDC (${amount} base units)`);

  const balanceBefore = await publicClient.readContract({
    address: USDC,
    abi: erc20Abi,
    functionName: 'balanceOf',
    args: [account.address],
  });
  console.log(`Sender balance before: ${formatUnits(balanceBefore, DECIMALS)} USDC`);

  if (balanceBefore < amount) {
    console.error('Insufficient balance');
    process.exit(1);
  }

  const hash = await walletClient.writeContract({
    address: USDC,
    abi: erc20Abi,
    functionName: 'transfer',
    args: [to, amount],
  });
  console.log(`Tx hash: ${hash}`);

  const receipt = await publicClient.waitForTransactionReceipt({ hash });
  console.log(`Status: ${receipt.status}  Block: ${receipt.blockNumber}`);

  const [balanceFromAfter, balanceToAfter] = await Promise.all([
    publicClient.readContract({
      address: USDC,
      abi: erc20Abi,
      functionName: 'balanceOf',
      args: [account.address],
    }),
    publicClient.readContract({
      address: USDC,
      abi: erc20Abi,
      functionName: 'balanceOf',
      args: [to],
    }),
  ]);
  console.log(`Sender balance after:    ${formatUnits(balanceFromAfter, DECIMALS)} USDC`);
  console.log(`Recipient balance after: ${formatUnits(balanceToAfter, DECIMALS)} USDC`);
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
