An "Other networks" table under the accounts: every profile the settings allow other than the selected one, each connected on demand and following heads like the main table, with the account's spendable and total balance there and the chain's state. One seed gives the same address on every Quantus-family chain (they share coin type 189189), and the table says so rather than pretending they are different accounts. Run on the dev network with testnets shown: Quantus mainnet through wss://quantus.blackbeard.observer at block 54032 and Planck at 1111122 listed beside the dev chain, both at zero for crystal_alice; a Polkadot address in the send form refused as "a Polkadot address, not a Local dev node address". Closes #37 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ftBXYuba8ARhQeF74oUgW
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import type { ChainProfile } from '../api/generated/ChainProfile'
|
||||
import { useBalances, useChainStatus, useChains, useSession, useSettings } from '../api/hooks'
|
||||
import { formatAmount } from '../lib/format'
|
||||
|
||||
/**
|
||||
* The same accounts on every other network the wallet knows, side by
|
||||
* side. Quantus-family chains share coin type 189189, so one seed gives
|
||||
* the same address on each of them; the balances differ, and a testnet's
|
||||
* is not money. Each row connects its chain on demand and follows heads
|
||||
* like the main table.
|
||||
*/
|
||||
export function NetworkOverview() {
|
||||
const chains = useChains()
|
||||
const settings = useSettings()
|
||||
const session = useSession()
|
||||
if (!chains.data || !settings.data || !session.data || session.data.locked) return null
|
||||
const others = chains.data.filter(
|
||||
(c) =>
|
||||
c.id !== settings.data!.network && (c.kind === 'mainnet' || settings.data!.show_testnets),
|
||||
)
|
||||
if (others.length === 0) return null
|
||||
return (
|
||||
<section className="panel">
|
||||
<div className="panel-head">
|
||||
<h2 className="panel-title">Other networks</h2>
|
||||
<span className="muted" style={{ fontSize: 12 }}>
|
||||
one seed, the same addresses on every Quantus-family chain
|
||||
</span>
|
||||
</div>
|
||||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Network</th>
|
||||
<th>Address</th>
|
||||
<th className="num">Spendable</th>
|
||||
<th className="num">Total</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{others.map((c) => (
|
||||
<ChainRows key={c.id} profile={c} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
function ChainRows({ profile }: { profile: ChainProfile }) {
|
||||
const status = useChainStatus(profile.id)
|
||||
const balances = useBalances(profile.id, true)
|
||||
const session = useSession()
|
||||
const accounts = session.data?.accounts ?? []
|
||||
const state = status.data?.connected
|
||||
? `block ${status.data.best_number ?? '…'}`
|
||||
: (status.data?.last_error ?? 'connecting…')
|
||||
return (
|
||||
<>
|
||||
{accounts.map((a, i) => {
|
||||
const b = balances.data?.find((x) => x.address === a.address)
|
||||
return (
|
||||
<tr key={`${profile.id}-${a.address}`} data-testid={`overview-${profile.id}`}>
|
||||
<td>
|
||||
{i === 0 && (
|
||||
<>
|
||||
{profile.display_name}
|
||||
{profile.kind !== 'mainnet' && (
|
||||
<>
|
||||
{' '}
|
||||
<span className="chip testnet">{profile.kind}</span>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
<td className="mono">{a.address}</td>
|
||||
<td className="num numeral">{b ? `${formatAmount(b.spendable)} ${b.symbol}` : '…'}</td>
|
||||
<td className="num numeral">{b ? `${formatAmount(b.total)} ${b.symbol}` : '…'}</td>
|
||||
<td className="muted" style={{ fontSize: 12 }}>
|
||||
{i === 0 && state}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useBalances, useChains, useSession, useSettings } from '../api/hooks'
|
||||
import { AccountName } from '../components/AccountName'
|
||||
import { ChainCaveat } from '../components/ChainCaveat'
|
||||
import { NetworkOverview } from '../components/NetworkOverview'
|
||||
import { PendingReversibleList } from '../components/PendingReversible'
|
||||
import { formatAmount } from '../lib/format'
|
||||
|
||||
@@ -80,6 +81,7 @@ export function Accounts() {
|
||||
{chain && profile && unlocked && (
|
||||
<PendingReversibleList chain={chain} profile={profile} addresses={addresses} />
|
||||
)}
|
||||
<NetworkOverview />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user