Исправить клиентскую Solana-регистрацию после ухода от Anchor
This commit is contained in:
parent
b0b8c7a445
commit
6bf5d1d5ed
@ -0,0 +1,30 @@
|
|||||||
|
# Клиентская Solana-регистрация после ухода от Anchor
|
||||||
|
|
||||||
|
## Краткое описание
|
||||||
|
|
||||||
|
Исправлен рассинхрон обычного клиентского UI с no-Anchor ABI программ:
|
||||||
|
|
||||||
|
- `shine_login_guard`
|
||||||
|
- `shine_users`
|
||||||
|
|
||||||
|
Исправлены клиентские вызовы:
|
||||||
|
|
||||||
|
1. Solana-предпроверка логина в обычном UI.
|
||||||
|
2. `init_users_economy_config` в обычном UI.
|
||||||
|
|
||||||
|
## Что проверять
|
||||||
|
|
||||||
|
1. На странице регистрации проверка свободного логина не выдаёт `InvalidInstructionData`.
|
||||||
|
2. Для свободного обычного логина отображается корректный статус без fallback-предупреждения про недоступную Solana-предпроверку.
|
||||||
|
3. Регистрация пользователя через обычный UI проходит до конца.
|
||||||
|
4. Страница `Solana: init регистрации` в обычном UI отправляет корректную транзакцию и не падает из-за старого Anchor discriminator.
|
||||||
|
|
||||||
|
## Ожидаемый результат
|
||||||
|
|
||||||
|
1. `shine_login_guard` принимает клиентский precheck.
|
||||||
|
2. `init_users_economy_config` из обычного UI совместим с текущей программой `shine_users`.
|
||||||
|
3. Обычный клиентский UI ведёт себя так же, как серверный UI, там где используется общий no-Anchor путь.
|
||||||
|
|
||||||
|
## Статус
|
||||||
|
|
||||||
|
- `pending`
|
||||||
@ -1,2 +1,2 @@
|
|||||||
client.version=1.2.132
|
client.version=1.2.133
|
||||||
server.version=1.2.124
|
server.version=1.2.125
|
||||||
|
|||||||
@ -116,7 +116,6 @@ export function render({ navigate }) {
|
|||||||
const connection = new solana.Connection(String(state.entrySettings.solanaServer || ''), 'confirmed');
|
const connection = new solana.Connection(String(state.entrySettings.solanaServer || ''), 'confirmed');
|
||||||
const programPubkey = new solana.PublicKey(programId);
|
const programPubkey = new solana.PublicKey(programId);
|
||||||
|
|
||||||
const discriminator = Uint8Array.from([13, 16, 103, 175, 121, 137, 166, 222]);
|
|
||||||
const ix = new solana.TransactionInstruction({
|
const ix = new solana.TransactionInstruction({
|
||||||
programId: programPubkey,
|
programId: programPubkey,
|
||||||
keys: [
|
keys: [
|
||||||
@ -124,7 +123,7 @@ export function render({ navigate }) {
|
|||||||
{ pubkey: economyPda, isSigner: false, isWritable: true },
|
{ pubkey: economyPda, isSigner: false, isWritable: true },
|
||||||
{ pubkey: solana.SystemProgram.programId, isSigner: false, isWritable: false },
|
{ pubkey: solana.SystemProgram.programId, isSigner: false, isWritable: false },
|
||||||
],
|
],
|
||||||
data: discriminator,
|
data: Uint8Array.from([1]),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash('confirmed');
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import {
|
|||||||
SHINE_LOGIN_GUARD_PROGRAM_ID,
|
SHINE_LOGIN_GUARD_PROGRAM_ID,
|
||||||
} from '../solana-programs.js';
|
} from '../solana-programs.js';
|
||||||
|
|
||||||
const CLASSIFY_LOGIN_DISCRIMINATOR = new Uint8Array([112, 97, 152, 32, 255, 73, 108, 86]);
|
const CLASSIFY_LOGIN_INSTRUCTION_TAG = 1;
|
||||||
const PRECHECK_SIM_PAYER = 'FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P';
|
const PRECHECK_SIM_PAYER = 'FUc28vNixp7F3nnkpGVt6nuJbgvJ4429v4B5wS52Df6P';
|
||||||
|
|
||||||
let solanaLibPromise = null;
|
let solanaLibPromise = null;
|
||||||
@ -33,7 +33,7 @@ class BorshBuf {
|
|||||||
|
|
||||||
function serializeClassifyLoginArgs(login) {
|
function serializeClassifyLoginArgs(login) {
|
||||||
const b = new BorshBuf();
|
const b = new BorshBuf();
|
||||||
b.raw(CLASSIFY_LOGIN_DISCRIMINATOR);
|
b.u8(CLASSIFY_LOGIN_INSTRUCTION_TAG);
|
||||||
b.str(String(login || ''));
|
b.str(String(login || ''));
|
||||||
return b.result();
|
return b.result();
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ export async function precheckLoginClassOnSolana({ login, solanaEndpoint }) {
|
|||||||
const payer = new solana.PublicKey(PRECHECK_SIM_PAYER);
|
const payer = new solana.PublicKey(PRECHECK_SIM_PAYER);
|
||||||
const ix = new solana.TransactionInstruction({
|
const ix = new solana.TransactionInstruction({
|
||||||
programId: loginGuardProgram,
|
programId: loginGuardProgram,
|
||||||
keys: [{ pubkey: payer, isSigner: true, isWritable: false }],
|
keys: [],
|
||||||
data: serializeClassifyLoginArgs(String(login || '').toLowerCase()),
|
data: serializeClassifyLoginArgs(String(login || '').toLowerCase()),
|
||||||
});
|
});
|
||||||
const { blockhash } = await connection.getLatestBlockhash('confirmed');
|
const { blockhash } = await connection.getLatestBlockhash('confirmed');
|
||||||
|
|||||||
41
shine-solana/shine/doc/shine_payments_e2e_test_plan.md
Normal file
41
shine-solana/shine/doc/shine_payments_e2e_test_plan.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# План тестирования `shine_payments` после переписи без Anchor и добавления `Q3`
|
||||||
|
|
||||||
|
## Назначение документа
|
||||||
|
|
||||||
|
Это не описание бизнес-логики программы и не формат PDA.
|
||||||
|
|
||||||
|
Это отдельный план ручной и полуавтоматической проверки для сценария:
|
||||||
|
|
||||||
|
- перепись `shine_payments` на чистый `solana_program`;
|
||||||
|
- отказ от `programs/common`;
|
||||||
|
- добавление очереди `Q3`;
|
||||||
|
- обновление тестового HTML UI.
|
||||||
|
|
||||||
|
## Что проверять
|
||||||
|
|
||||||
|
1. Деплой новой версии программы и единый актуальный `program id` в коде и UI.
|
||||||
|
2. Однократный `init` на пустых PDA.
|
||||||
|
3. Покупку билетов через `buy_ticket_usd` и `buy_ticket_sol`.
|
||||||
|
4. DAO-управление:
|
||||||
|
- `update_coef_limit`
|
||||||
|
- `grant_manager_limits`
|
||||||
|
5. Создание менеджерских тикетов во все три очереди:
|
||||||
|
- `Q1`
|
||||||
|
- `Q2`
|
||||||
|
- `Q3`
|
||||||
|
6. Приоритет выплат:
|
||||||
|
- сначала `Q1`
|
||||||
|
- потом `Q2`
|
||||||
|
- потом `Q3`
|
||||||
|
7. Частичные выплаты с минимальным пополнением `inflow_vault`.
|
||||||
|
8. Повторную покупку билета между выплатами.
|
||||||
|
9. Финальное погашение всех очередей.
|
||||||
|
10. Возврат максимально возможных остатков лампортов на базовый кошелёк.
|
||||||
|
|
||||||
|
## Где смотреть подробный сценарий
|
||||||
|
|
||||||
|
Актуальный подробный сценарий тестирования и его статус ведётся в:
|
||||||
|
|
||||||
|
- `Dev_Docs/Pending_Features/2026-06-06_1659_shine_payments_e2e_перепись_и_q3.md`
|
||||||
|
|
||||||
|
Этот файл в `shine-solana/shine/doc/` оставлен как постоянная заметка, что у программы есть отдельный e2e-план проверки.
|
||||||
Loading…
Reference in New Issue
Block a user