Improvements

This commit is contained in:
2026-10-20 04:07:37 -04:00
parent 0cc5032857
commit 3cee89d023
20 changed files with 511 additions and 23 deletions
+3 -1
View File
@@ -13,6 +13,7 @@ import { ThemePicker } from './ThemePicker.tsx';
import { TradeDesk } from './TradeDesk.tsx';
import { Marketplace } from './Marketplace.tsx';
import { IS_MAINNET, NETWORK_LABEL } from '../shared/network.ts';
import { StateClient } from '../shared/rpc-client.ts';
import './App.css';
import './testnet.css';
@@ -59,12 +60,13 @@ export default function App() {
const transferInFlight = useRef(false);
const refreshVersion = useRef(0);
const minerPanel = useRef<HTMLElement>(null);
const stateClient = useRef(new StateClient());
useModalFocus(Boolean(dialog || selected));
const refresh = async () => {
const version = ++refreshVersion.current;
try {
const data = await request<TestnetSnapshot>('state');
const data = await stateClient.current.load();
if (data.network !== NETWORK || data.algorithm !== 'RandomX' || typeof data.chainId !== 'string' ||
!Array.isArray(data.blocks) || !Array.isArray(data.transfers) || !Array.isArray(data.pendingTransfers))
throw new Error('Incompatible node. This interface requires the Wikideck RandomX testnet API.');
+4 -2
View File
@@ -4,6 +4,8 @@ import { CONSENSUS, NETWORK, isNftTrade, nftTradeMessage, type NftTrade, type Te
import { tradeOfferSchema, type TradeOffer } from '../shared/trade-offer.ts';
import type { Wallet } from './wallet.ts';
import './trade.css';
import { StateClient } from '../shared/rpc-client.ts';
const stateClient = new StateClient();
type Props = { wallet?: Wallet; snapshot?: TestnetSnapshot; rpcAvailable: boolean; onNotice: (message: string) => void };
type OwnedCard = TestnetDeck['nfts'][number];
@@ -124,7 +126,7 @@ export function TradeDesk({ wallet, snapshot, rpcAvailable, onNotice }: Props) {
}
setBusy(true); setOfferError('');
try {
const fresh = await api<TestnetSnapshot>('state');
const fresh = await stateClient.load();
if (fresh.chainId !== snapshot.chainId || remoteDeck.chainId !== fresh.chainId) throw new Error('Chain changed. Refresh and rebuild the trade.');
const offeredLegs = [...offered].map(cardHash => {
const card = myDeck.find(item => item.block.tokenId === cardHash);
@@ -166,7 +168,7 @@ export function TradeDesk({ wallet, snapshot, rpcAvailable, onNotice }: Props) {
if (offer.network !== NETWORK || offer.chainId !== snapshot.chainId) throw new Error('Offer is for another network or chain.');
if (offer.counterparty !== wallet.address) throw new Error('This offer is addressed to a different wallet.');
if (!await verifyOfferSignature(offer)) throw new Error('The proposer signature is invalid; do not accept this offer.');
const fresh = await api<TestnetSnapshot>('state');
const fresh = await stateClient.load();
if (fresh.chainId !== offer.chainId) throw new Error('The chain changed. Reload and review the offer again.');
for (const leg of offer.offered) {
const block = fresh.blocks.find(item => item.tokenId === leg.cardHash);