SHiNE-server/scripts/devnet/test_login_guard_precheck.js

88 lines
2.6 KiB
JavaScript

#!/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 <login>');
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);
});