Кошелёк Сияния: фактический расход с сервера, доработка UI и topup через compute budget

This commit is contained in:
AidarKC 2026-05-30 11:53:36 +04:00
parent edc94d3700
commit b75ac46781
5 changed files with 17 additions and 27 deletions

View File

@ -1,2 +1,2 @@
client.version=1.2.99 client.version=1.2.100
server.version=1.2.93 server.version=1.2.94

View File

@ -6,7 +6,7 @@
<link rel="manifest" href="./manifest.webmanifest" /> <link rel="manifest" href="./manifest.webmanifest" />
<title>Shine UI Demo</title> <title>Shine UI Demo</title>
<script> <script>
window.__SHINE_BUILD_HASH__ = '20260530000600'; window.__SHINE_BUILD_HASH__ = '20260530000700';
window.__SHINE_CLIENT_VERSION__ = '1.2.8'; window.__SHINE_CLIENT_VERSION__ = '1.2.8';
</script> </script>
<script> <script>

View File

@ -47,7 +47,7 @@ import * as keyStorageView from './pages/key-storage-view.js';
import * as profileView from './pages/profile-view.js'; import * as profileView from './pages/profile-view.js';
import * as profileEditView from './pages/profile-edit-view.js'; import * as profileEditView from './pages/profile-edit-view.js';
import * as walletView from './pages/wallet-view.js?v=202605300006'; import * as walletView from './pages/wallet-view.js?v=202605300007';
import * as settingsView from './pages/settings-view.js'; import * as settingsView from './pages/settings-view.js';
import * as developerSettingsView from './pages/developer-settings-view.js'; import * as developerSettingsView from './pages/developer-settings-view.js';
import * as serverSettingsView from './pages/server-settings-view.js'; import * as serverSettingsView from './pages/server-settings-view.js';

View File

@ -24,7 +24,7 @@ import {
getShineBlockchainUsage, getShineBlockchainUsage,
getShineUsersEconomyConfig, getShineUsersEconomyConfig,
updateShineUserPdaOnSolana, updateShineUserPdaOnSolana,
} from '../services/shine-blockchain-wallet-service.js?v=2026052803'; } from '../services/shine-blockchain-wallet-service.js?v=202605300007';
export const pageMeta = { id: 'wallet-view', title: 'Кошелёк' }; export const pageMeta = { id: 'wallet-view', title: 'Кошелёк' };
const SOLANA_PRIVATE_BASE58_MAX_LEN = 44; const SOLANA_PRIVATE_BASE58_MAX_LEN = 44;
@ -159,14 +159,14 @@ export function render({ navigate }) {
const usedLabel = document.createElement('p'); const usedLabel = document.createElement('p');
usedLabel.className = 'meta-muted'; usedLabel.className = 'meta-muted';
usedLabel.textContent = 'Израсходовано (закреплено в Solana)'; usedLabel.textContent = 'Израсходовано (фактически на сервере)';
const usedValue = document.createElement('h2'); const usedValue = document.createElement('h2');
usedValue.style.fontSize = '26px'; usedValue.style.fontSize = '26px';
usedValue.textContent = '— KB'; usedValue.textContent = '— KB';
const leftLabel = document.createElement('p'); const leftLabel = document.createElement('p');
leftLabel.className = 'meta-muted'; leftLabel.className = 'meta-muted';
leftLabel.textContent = 'Осталось (по Solana)'; leftLabel.textContent = 'Осталось';
const leftValue = document.createElement('h2'); const leftValue = document.createElement('h2');
leftValue.style.fontSize = '30px'; leftValue.style.fontSize = '30px';
leftValue.textContent = '— KB'; leftValue.textContent = '— KB';
@ -185,11 +185,8 @@ export function render({ navigate }) {
updatedLabel.textContent = 'Обновлено: —'; updatedLabel.textContent = 'Обновлено: —';
const serverTitle = document.createElement('h3'); const serverTitle = document.createElement('h3');
serverTitle.style.margin = '8px 0 0'; serverTitle.style.margin = '14px 0 0';
serverTitle.textContent = 'Фактическое состояние на сервере'; serverTitle.textContent = 'Фактическое состояние на сервере';
const serverBlocksLabel = document.createElement('p');
serverBlocksLabel.className = 'meta-muted';
serverBlocksLabel.textContent = 'Блоков: —';
const serverSizeLabel = document.createElement('p'); const serverSizeLabel = document.createElement('p');
serverSizeLabel.className = 'meta-muted'; serverSizeLabel.className = 'meta-muted';
serverSizeLabel.textContent = 'Размер цепочки: —'; serverSizeLabel.textContent = 'Размер цепочки: —';
@ -203,11 +200,8 @@ export function render({ navigate }) {
serverLastHashLabel.textContent = 'Hash: —'; serverLastHashLabel.textContent = 'Hash: —';
const solanaTitle = document.createElement('h3'); const solanaTitle = document.createElement('h3');
solanaTitle.style.margin = '8px 0 0'; solanaTitle.style.margin = '14px 0 0';
solanaTitle.textContent = 'Закреплено в Solana'; solanaTitle.textContent = 'Закреплено в Solana';
const solanaBlocksLabel = document.createElement('p');
solanaBlocksLabel.className = 'meta-muted';
solanaBlocksLabel.textContent = 'Блоков: —';
const solanaLastLabel = document.createElement('p'); const solanaLastLabel = document.createElement('p');
solanaLastLabel.className = 'meta-muted'; solanaLastLabel.className = 'meta-muted';
solanaLastLabel.textContent = 'Крайний блок: —'; solanaLastLabel.textContent = 'Крайний блок: —';
@ -228,12 +222,10 @@ export function render({ navigate }) {
endpointLabel, endpointLabel,
updatedLabel, updatedLabel,
serverTitle, serverTitle,
serverBlocksLabel,
serverSizeLabel, serverSizeLabel,
serverLastLabel, serverLastLabel,
serverLastHashLabel, serverLastHashLabel,
solanaTitle, solanaTitle,
solanaBlocksLabel,
solanaLastLabel, solanaLastLabel,
solanaLastHashLabel, solanaLastHashLabel,
); );
@ -257,7 +249,6 @@ export function render({ navigate }) {
sizeBytes: Number(user.serverBlockchainSizeBytes || 0), sizeBytes: Number(user.serverBlockchainSizeBytes || 0),
sizeLimitBytes: Number(user.serverBlockchainSizeLimitBytes || 0), sizeLimitBytes: Number(user.serverBlockchainSizeLimitBytes || 0),
lastNumber, lastNumber,
blocksCount: lastNumber >= 0 ? (lastNumber + 1) : 0,
lastHash: String(user.serverLastGlobalHash || ''), lastHash: String(user.serverLastGlobalHash || ''),
}; };
}; };
@ -314,22 +305,19 @@ export function render({ navigate }) {
fetchServerState(), fetchServerState(),
]); ]);
if (modeToken !== activeModeToken) return; if (modeToken !== activeModeToken) return;
const solanaBlocks = usage.lastBlockNumber >= 0 ? usage.lastBlockNumber + 1 : 0;
const serverBlocks = serverState.blocksCount;
limitValue.textContent = formatKbFromBytes(usage.paidLimitBytes); limitValue.textContent = formatKbFromBytes(usage.paidLimitBytes);
usedValue.textContent = formatKbFromBytes(usage.usedBytes); const usedServerBytes = BigInt(Math.max(0, Number(serverState.sizeBytes || 0)));
leftValue.textContent = formatKbFromBytes(usage.leftBytes); const leftServerBytes = usage.paidLimitBytes > usedServerBytes ? (usage.paidLimitBytes - usedServerBytes) : 0n;
usedValue.textContent = formatKbFromBytes(usedServerBytes);
leftValue.textContent = formatKbFromBytes(leftServerBytes);
pdaLabel.textContent = `PDA: ${usage.userPda}`; pdaLabel.textContent = `PDA: ${usage.userPda}`;
endpointLabel.textContent = `RPC: ${usage.endpoint}`; endpointLabel.textContent = `RPC: ${usage.endpoint}`;
updatedLabel.textContent = `Обновлено: ${nowRu()}`; updatedLabel.textContent = `Обновлено: ${nowRu()}`;
serverBlocksLabel.textContent = `Блоков: ${serverBlocks.toLocaleString('ru-RU')}`; serverSizeLabel.textContent = `Размер цепочки: ${formatKbFromBytes(serverState.sizeBytes)}`;
serverSizeLabel.textContent = `Размер цепочки: ${formatKbFromBytes(serverState.sizeBytes)} из ${formatKbFromBytes(serverState.sizeLimitBytes)}`;
serverLastLabel.textContent = `Крайний блок: ${serverState.lastNumber}`; serverLastLabel.textContent = `Крайний блок: ${serverState.lastNumber}`;
serverLastHashLabel.textContent = `Hash: ${serverState.lastHash || '—'}`; serverLastHashLabel.textContent = `Hash: ${serverState.lastHash || '—'}`;
solanaBlocksLabel.textContent = `Блоков: ${solanaBlocks.toLocaleString('ru-RU')}`;
solanaLastLabel.textContent = `Крайний блок: ${usage.lastBlockNumber}`; solanaLastLabel.textContent = `Крайний блок: ${usage.lastBlockNumber}`;
solanaLastHashLabel.textContent = `Hash: ${usage.lastBlockHashHex || '—'}`; solanaLastHashLabel.textContent = `Hash: ${usage.lastBlockHashHex || '—'}`;

View File

@ -457,10 +457,12 @@ export async function updateShineUserPdaOnSolana({
], ],
data: ixData, data: ixData,
}); });
const computeIx = solana.ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 });
const heapIx = solana.ComputeBudgetProgram.requestHeapFrame({ bytes: 131_072 });
const signature = await solana.sendAndConfirmTransaction( const signature = await solana.sendAndConfirmTransaction(
connection, connection,
new solana.Transaction().add(edIxRoot, edIxBch, updIx), new solana.Transaction().add(computeIx, heapIx, edIxRoot, edIxBch, updIx),
[deviceKeypair], [deviceKeypair],
{ commitment: 'confirmed' }, { commitment: 'confirmed' },
); );