Files
subochev b8a1f8dc39 docs(sec): SEC-9 закрыт — возврат залога при ничьей
Сводка: открыто 8 (было 9), закрыто 8. SEC-9 перенесён в закрытые с полной
историей: причина (close_bet.rs:66), замер доли ничьих (33.6%), решение
владельца (правка контракта), состав правок, собственная мутационная приёмка,
деплой и живой эффект (залипшие #0/#1 закрылись сами, ваулт −1000).
Хвост SEC-8 о «вечном залипании» помечен как устранённый.

Инструменты приёмки:
- tie-refund-accept.cjs — ставки циклом, проверка статуса на цепи
  (живой прогон: 6 возвратов из 25 ставок)
- tie-distribution.cjs, policy-economics.cjs — выбор политики ничьей
- vault-check.cjs — разбор Bet-аккаунтов сырыми байтами
2026-09-14 02:19:28 +03:00

43 lines
2.2 KiB
JavaScript

// Разбор Bet-аккаунтов программы напрямую (Anchor в релейере нет).
const { Connection, PublicKey } = require('@solana/web3.js');
const CV = new PublicKey('9ALsnxXNzDBv3mokngCHbruRTWUZiWR7pf7vswS1fCpf');
const MINT = new PublicKey('6fxySAjTQTkzyyZ7u8EQqv3SyJtv2Ydr6hphquHbkGS9');
const conn = new Connection('http://192.168.76.181:8899', 'confirmed');
const [vaultAuth] = PublicKey.findProgramAddressSync(
[Buffer.from('global'), Buffer.from('vault')], CV);
(async () => {
const accs = await conn.getProgramAccounts(CV);
const bets = [];
for (const { pubkey, account } of accs) {
const d = account.data;
if (d.length !== 96) continue;
// Раскладка Bet (state.rs): 8 disc | amount(0) bet_time(8) expire_time(16)
// entry_price(24) exit_price(32) side(40) status(48) bettor(56..88)
const u64 = (o) => Number(d.readBigUInt64LE(8 + o));
const i64 = (o) => Number(d.readBigInt64LE(8 + o));
bets.push({
pda: pubkey.toBase58().slice(0, 8),
bettor: new PublicKey(d.subarray(8 + 56, 8 + 88)).toBase58().slice(0, 8),
side: u64(40) === 0 ? 'UP' : 'DOWN',
amount: u64(0),
betTime: i64(8),
expireTime: i64(16),
entryPrice: u64(24),
exitPrice: u64(32),
status: ['open', 'payout_done', 'house_won'][u64(48)] ?? 'status=' + u64(48),
});
}
console.log('Bet-аккаунтов:', bets.length);
for (const b of bets) console.log(` ${b.pda}… ${b.side.padEnd(4)} amt=${b.amount} entry=${b.entryPrice} exit=${b.exitPrice} status=${b.status} expire=${new Date(b.expireTime * 1000).toISOString().slice(11, 19)}`);
const open = bets.filter((b) => b.status === 'open');
console.log('--- в статусе open:', open.length, '| заперто:', open.reduce((s, b) => s + b.amount, 0));
console.log('--- vault_authority PDA:', vaultAuth.toBase58());
const v = await conn.getTokenAccountsByOwner(vaultAuth, { mint: MINT });
for (const { pubkey, account } of v.value) {
console.log(' ваулт', pubkey.toBase58().slice(0, 10) + '…', 'держит:', account.data.readBigUInt64LE(64).toString());
}
})().catch((e) => console.log('ERR', e.message));