/**
 * Shared low-level ABI encoding helpers for /api/x402/actions/* tx-prepare endpoints.
 *
 * These build raw calldata for unsigned transactions returned to the caller.
 * The caller signs locally with their wallet — we never see or hold private keys.
 */

export const CHAIN_IDS: Record<string, number> = {
  base: 8453,
  avalanche: 43114,
  arbitrum: 42161,
  polygon: 137,
};

export const RPC_URLS: Record<string, string> = {
  base: 'https://base-rpc.publicnode.com',
  avalanche: 'https://api.avax.network/ext/bc/C/rpc',
  arbitrum: 'https://arb1.arbitrum.io/rpc',
  polygon: 'https://polygon-bor-rpc.publicnode.com',
};

export const EXPLORERS: Record<string, string> = {
  base: 'https://basescan.org',
  avalanche: 'https://snowtrace.io',
  arbitrum: 'https://arbiscan.io',
  polygon: 'https://polygonscan.com',
};

export const IDENTITY_REGISTRY: Record<string, string> = {
  base: '0xa7BD20bf5De63df949cA5Be2F20835978eCba81A',
  avalanche: '0x7448057C95Fb8a8B974a566cdcc9Cd042166A3f8',
  arbitrum: '0x83dd216449B3F0574E39043ECFE275946fa492e9',
  polygon: '0xD9bF6D92a1D9ee44a48c38481c046a819CBdf2ba',
};

export const REPUTATION_STAKING: Record<string, string> = {
  base: '0xd42BBfD3061A38D4B5540317A31D90212380069b',
  avalanche: '0x32211773C8266774A704aeD471f8eF073f34bA79',
  arbitrum: '0x9d4AbeAa8201e6f1649c296dd179Bbb3c401f96F',
  polygon: '0x3ceA2B0853B76Ac75603C1fa2A29D96A4467Bb79',
};

export const PARTNERSHIP_BONDS: Record<string, string> = {
  base: '0x01C479F0c039fEC40c0Cf1c5C921bab457d57441',
  avalanche: '0xDC8447c66fE9D9c7D54607A98346A15324b7985D',
  arbitrum: '0xf92baef9523BC264144F80F9c31D5c5C017c6Da8',
  polygon: '0xC574CF2a09B0B470933f0c6a3ef422e3fb25b4b4',
};

export const ACCOUNTABILITY_BONDS: Record<string, string> = {
  base: '0x6750D28865434344e04e1D0a6044394b726C3dfE',
  avalanche: '0x376831fB2457E34559891c32bEb61c442053C066',
  arbitrum: '0xdB54B8925664816187646174bdBb6Ac658A55a5F',
  polygon: '0x83dd216449B3F0574E39043ECFE275946fa492e9',
};

export const REPUTATION_REGISTRY: Record<string, string> = {
  base: '0x98afd1440B2238D73c1394720277a6d031fCbbD0',
  avalanche: '0x5DB1B4b412b80d03819395794fCcF5A73BF30656',
  arbitrum: '0x54e00081978eE2C8d9Ada8e9975B0Bb543D06A55',
  polygon: '0xf92baef9523BC264144F80F9c31D5c5C017c6Da8',
};

export const VALIDATION_REGISTRY: Record<string, string> = {
  base: '0x8D3495772EAcAdB7dC09F1784eF06F2D109fb8a5',
  avalanche: '0x44f1241F5F1A76c146d580142E54590a130410B4',
  arbitrum: '0x8B8Ba34F8AAB800F0Ba8391fb1388c6EFb911F92',
  polygon: '0x54e00081978eE2C8d9Ada8e9975B0Bb543D06A55',
};

export const ADAPTER: Record<string, string> = {
  base: '0x8bEFe7411AecddA6E1Aea8F031fedD293Ca7372E',
  avalanche: '0x69D3458aba750Fa85d4a25b3A23B398A3D9494fe',
  arbitrum: '0xa5CEC47B48999EB398707838E3A18dd20A1ae272',
  polygon: '0xBBC0EFdEE23854e7cb7C4c0f56fF7670BB0530A4',
};

export const MISSION_ENFORCEMENT: Record<string, string> = {
  base: '0xBc4208A7A59af3B7E438d3308C3dc0d299d739a7',
  avalanche: '0xA4F4EDd4ed280Bd784650c048190fBA16e0AFd11',
  arbitrum: '0x35978DB675576598F0781dA2133E94cdCf4858bC',
  polygon: '0x722E37A7D6f27896C688336AaaFb0dDA80D25E57',
};

export const ANTI_SURVEILLANCE: Record<string, string> = {
  base: '0xaaC44F1396f3F5b3C06048a1F819DC9b0f86D90c',
  avalanche: '0x7b9293B05Bd0fcb7458d06A364078761B8E8848e',
  arbitrum: '0x35978DB675576598F0781dA2133E94cdCf4858bC',
  polygon: '0x722E37A7D6f27896C688336AaaFb0dDA80D25E57',
};

export const DILITHIUM_ATTESTOR: Record<string, string> = {
  base: '0xef703bBe9b21960ede3e96abBB0Bbd0c525Fe050',
  avalanche: '0x9CF1fcba0c657e9FD807a9c8c028E0ef561b6B56',
  arbitrum: '0xf757f8650109cE7a89dd8f041DE69D861B64DD23',
  polygon: '0xf757f8650109cE7a89dd8f041DE69D861B64DD23',
};

export const TASK_ESCROW: Record<string, string> = {
  base: '0x70098737Cb41827b7a86397B42c166020BCcC03b',
  avalanche: '0xa7BD20bf5De63df949cA5Be2F20835978eCba81A',
  arbitrum: '0x5F7680a9a720c03812532A735D1165D9f97c0Cd1',
  polygon: '0x69D3458aba750Fa85d4a25b3A23B398A3D9494fe',
};

// VaultfireStreetCred — ERC-5192 soulbound reputation badge (Base-only)
export const STREET_CRED: Record<string, string> = {
  base: '0x5CfAB4B12718549e156D3642f9C63476aC4c2f99',
};

// === Tier 6 contract address maps ===

export const VKP_SESSION_KEY_MANAGER: Record<string, string> = {
  base: '0x18622Fd3DF3269Ef3cf53cF374eB011A36DC4Be5',
  avalanche: '0xE02F5029fcDd6c51e957eb3895bd5805126A5Cdc',
  arbitrum: '0x796d903923a0f4264E5B4dB46013cB186Fc610E2',
  polygon: '0x4A614DB779e38B47952DCCc2e88F0A6afb35c419',
};

export const VKP_FACTORY: Record<string, string> = {
  base: '0x174E29E6FAdD3096387030429Eb4677eA569e625',
  avalanche: '0x12f3e926122DB6A9A65740b90981c947EF18aC40',
  arbitrum: '0x65adEd8CCAe58FD3fAd6a84BDA323C78d9eD4269',
  polygon: '0x1d7eDE881093748B0a6feBc47cA9D681C19d8333',
};

export const VKP_DELEGATION_REGISTRY: Record<string, string> = {
  base: '0xd4d32b5c28040AFA2A6aB0ae9FF6DA68EAee4F82',
  avalanche: '0x3f385774dba7d067cda7E5190a659029BF8219dB',
  arbitrum: '0xA505996f4A1291DD7a6981Ab825E35418b2711de',
  polygon: '0x064d7e8a3A24909ef83d537dBA10Dfcd3D44912C',
};

// VaultfireNameService — Avalanche has no VNS deployment
export const VNS: Record<string, string> = {
  base: '0xA9e6c2c0a731F1f56F6720Dfac2eB1440Ab9453a',
  arbitrum: '0x7448057C95Fb8a8B974a566cdcc9Cd042166A3f8',
  polygon: '0x7448057C95Fb8a8B974a566cdcc9Cd042166A3f8',
};

export const BOND_INSURANCE_POOL: Record<string, string> = {
  base: '0xa074e372d5221b605E9762e41B86EbdBEBF1a978',
  avalanche: '0xf7B2dC73Ec69528F171F4a0ded62da557866BaA5',
  arbitrum: '0xAca6fe18917a985F6741FB986461B976e2A0a5DB',
  polygon: '0x9CF1fcba0c657e9FD807a9c8c028E0ef561b6B56',
};

export const CAPABILITY_CREDENTIALS: Record<string, string> = {
  base: '0x4C7fddDdae8855283e98dA80BDf7aEa51A0b772B',
  avalanche: '0x6750D28865434344e04e1D0a6044394b726C3dfE',
  arbitrum: '0x472dF1dD6D8218D0BF748e910E32861dAb88EDA6',
  polygon: '0x1762e484A48558Ea5Cd056ac2CDf43FBbA52ba58',
};

export const TRUST_ORACLE: Record<string, string> = {
  base: '0xF945aA87dB4E1d14aa7d0572501afa166374B776',
  avalanche: '0x01C479F0c039fEC40c0Cf1c5C921bab457d57441',
  arbitrum: '0xFeF83A66fC1f3c8311070FDd502cd90deD0B3C33',
  polygon: '0xFa8ed66E27379942cB90BB5f612F0170a5dE4924',
};

// VaultfireBatchOnboarder — EIP-7702 stateless delegate, Base-only
export const BATCH_ONBOARDER: Record<string, string> = {
  base: '0x82c6a0dd34F5cF57F8B98Ee118e911B977618890',
};

export const REPUTATION_DECAY: Record<string, string> = {
  base: '0xcDB75bECa0C56957FC79aB0dd470D4FcE2db6BC1',
  avalanche: '0xB622D2b555E6DEF9652108a61Ca8A00aA50f1D9F',
  arbitrum: '0x70098737Cb41827b7a86397B42c166020BCcC03b',
  polygon: '0x12f3e926122DB6A9A65740b90981c947EF18aC40',
};

export const TELEPORTER_BRIDGE: Record<string, string> = {
  base: '0x62edf0cBc8Fa3d98B6A07197DFE9cb1c128a7eC7',
  avalanche: '0x1762e484A48558Ea5Cd056ac2CDf43FBbA52ba58',
  arbitrum: '0x7b9293B05Bd0fcb7458d06A364078761B8E8848e',
  polygon: '0x7b9293B05Bd0fcb7458d06A364078761B8E8848e',
};

export const AGENT_SAFETY_MANAGER: Record<string, string> = {
  base: '0x6B580f08ecA90778AC41FA1290557c86DeEfB1F5',
  avalanche: '0xC46d9d20727060E563392A1F4DB00a3877807cb7',
  arbitrum: '0xa2bE41F6fA82dE27fbB7838A0308d05741C1e9c8',
  polygon: '0xCA5380aF3dd6a29C217cE0c0c9f45999B47cbdF3',
};

export const AGENT_SLA_ENFORCER: Record<string, string> = {
  base: '0xc0b7cFF13C7C7f4DAF36A7c67da47B2Cb311335D',
  avalanche: '0x6463434322B05bEb806F60161d5023529288aFF9',
  arbitrum: '0xF945aA87dB4E1d14aa7d0572501afa166374B776',
  polygon: '0x3f385774dba7d067cda7E5190a659029BF8219dB',
};

export const SCOPED_DELEGATION: Record<string, string> = {
  base: '0x716C4f0a822f8A7F73126aEe123ACa0Db225a3DC',
  avalanche: '0xD8A8c9604Af2Be2573c3a3102D5094654Da55971',
  arbitrum: '0xd42BBfD3061A38D4B5540317A31D90212380069b',
  polygon: '0xE02F5029fcDd6c51e957eb3895bd5805126A5Cdc',
};

export const FLOURISHING_METRICS_ORACLE: Record<string, string> = {
  base: '0xf7B2dC73Ec69528F171F4a0ded62da557866BaA5',
  avalanche: '0x1437c4081233A4f0B6907dDf5374Ed610cBD6B25',
  arbitrum: '0x54e00081978eE2C8d9Ada8e9975B0Bb543D06A55',
  polygon: '0xf92baef9523BC264144F80F9c31D5c5C017c6Da8',
};

export const MULTISIG_GOVERNANCE: Record<string, string> = {
  base: '0x34a19C7298aCA59e185F1ecfB352AC566bB4B4A9',
  avalanche: '0x3ceA2B0853B76Ac75603C1fa2A29D96A4467Bb79',
  arbitrum: '0x94F54c849692Cc64C35468D0A87D2Ab9D7Cb6Fb2',
  polygon: '0x5DB1B4b412b80d03819395794fCcF5A73BF30656',
};

export const SUPPORTED_CHAINS = ['base', 'avalanche', 'arbitrum', 'polygon'] as const;

export function encodeUint256(n: number | bigint): string {
  return BigInt(n).toString(16).padStart(64, '0');
}

export function encodeAddress(addr: string): string {
  return addr.replace(/^0x/, '').toLowerCase().padStart(64, '0');
}

export function encodeString(s: string): string {
  const utf8 = new TextEncoder().encode(s);
  const length = encodeUint256(utf8.length);
  const paddedLength = Math.ceil(utf8.length / 32) * 32;
  const padded = new Uint8Array(paddedLength);
  padded.set(utf8);
  let hex = '';
  for (const byte of padded) hex += byte.toString(16).padStart(2, '0');
  return length + hex;
}

export function encodeBytes32FromString(s: string): string {
  const hex = Array.from(new TextEncoder().encode(s))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('')
    .padEnd(64, '0')
    .slice(0, 64);
  return hex;
}

export function isValidAddress(addr: string): boolean {
  return /^0x[a-fA-F0-9]{40}$/.test(addr || '');
}

export function isValidBytes32(s: string): boolean {
  return /^0x[a-fA-F0-9]{64}$/.test(s || '');
}

export function encodeBytes32(hex: string): string {
  return hex.replace(/^0x/, '').padStart(64, '0').toLowerCase();
}

export function encodeBool(b: boolean): string {
  return encodeUint256(b ? 1 : 0);
}

/** Encode dynamic bytes (length + padded data). */
export function encodeDynamicBytes(hex: string): string {
  const clean = hex.replace(/^0x/, '');
  const byteLen = clean.length / 2;
  const length = encodeUint256(byteLen);
  const paddedLen = Math.ceil(byteLen / 32) * 32;
  const padded = clean.padEnd(paddedLen * 2, '0');
  return length + padded;
}

/** Keccak-256 of a UTF-8 string (returns 64-char hex, no 0x). */
export async function keccak256Utf8(s: string): Promise<string> {
  const { keccak_256 } = await import('@noble/hashes/sha3');
  const out = keccak_256(new TextEncoder().encode(s));
  return Array.from(out).map((b) => b.toString(16).padStart(2, '0')).join('');
}

export function isValidChain(chain: string): chain is typeof SUPPORTED_CHAINS[number] {
  return (SUPPORTED_CHAINS as readonly string[]).includes(chain);
}

export async function rpcCall(rpcUrl: string, method: string, params: unknown[]) {
  const res = await fetch(rpcUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params }),
    signal: AbortSignal.timeout(12000),
  });
  return res.json();
}

export async function estimateGas(rpc: string, from: string, to: string, data: string, value: string = '0x0'): Promise<string> {
  try {
    const r = await rpcCall(rpc, 'eth_estimateGas', [{ from, to, data, value }]);
    if (r.result) {
      const est = BigInt(r.result) * 12n / 10n;
      return est.toString();
    }
  } catch {
    // fall through
  }
  return '300000';
}

/** SECURITY: reject any request that looks like it contains a private key. */
export function rejectsPrivateKeyShape(body: any): string | null {
  if (!body) return null;
  if (body.privateKey || body.private_key || body.secret || body.mnemonic || body.seed) {
    return 'SECURITY: Private keys must never be sent to a server. Sign transactions client-side using your wallet (Base App, MetaMask, WalletConnect, etc.). Use the returned txData object with your wallet provider.';
  }
  return null;
}
