#!/usr/bin/env node /* eslint-disable no-console */ const crypto = require('crypto'); const web3 = require('@solana/web3.js'); const RPC = process.env.SOLANA_RPC || 'https://api.devnet.solana.com'; const LOGIN_GUARD_PROGRAM_ID = '3xkopA7cXagxzMFrKdv3NCBfV6BKiRJCk69kr27M2sRo'; const SIM_PAYER = 'FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P'; const login = String(process.argv[2] || '').trim().toLowerCase(); if (!login) { console.error('Usage: node scripts/devnet/test_login_guard_precheck.js '); process.exit(1); } function discriminator(name) { return crypto.createHash('sha256').update(`global:${name}`).digest().subarray(0, 8); } function encodeClassifyLoginData(loginValue) { const disc = discriminator('classify_login'); const str = Buffer.from(loginValue, 'utf8'); const len = Buffer.alloc(4); len.writeUInt32LE(str.length, 0); return Buffer.concat([disc, len, str]); } function decodeU32FromBase64(b64) { const bytes = Buffer.from(b64, 'base64'); if (bytes.length < 4) throw new Error('bad returnData'); return bytes.readUInt32LE(0); } async function main() { const connection = new web3.Connection(RPC, 'confirmed'); const programId = new web3.PublicKey(LOGIN_GUARD_PROGRAM_ID); const payer = new web3.PublicKey(SIM_PAYER); const ix = new web3.TransactionInstruction({ programId, keys: [{ pubkey: payer, isSigner: true, isWritable: false }], data: encodeClassifyLoginData(login), }); const { blockhash } = await connection.getLatestBlockhash('confirmed'); const v0 = new web3.TransactionMessage({ payerKey: payer, recentBlockhash: blockhash, instructions: [ix], }).compileToV0Message(); const tx = new web3.VersionedTransaction(v0); const sim = await connection.simulateTransaction(tx, { commitment: 'confirmed', sigVerify: false, replaceRecentBlockhash: true, }); if (sim?.value?.err) { console.error('Simulation error:', sim.value.err); console.error('Logs:', sim?.value?.logs || []); process.exit(2); } const returnData = sim?.value?.returnData; if (!returnData || returnData.programId !== LOGIN_GUARD_PROGRAM_ID) { console.error('No returnData from login_guard'); console.error(JSON.stringify(sim, null, 2)); process.exit(3); } const cls = decodeU32FromBase64(returnData.data[0]); const className = cls === 0 ? 'free' : cls === 1 ? 'premium' : cls === 2 ? 'company' : `unknown(${cls})`; console.log(JSON.stringify({ login, classCode: cls, className, logs: sim?.value?.logs || [], }, null, 2)); } main().catch((e) => { console.error(e?.stack || e?.message || String(e)); process.exit(10); });