Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# 更新日志

## [1.0.7] - 2026-02-18

修复钱包列表链水印映射并在地址前显示链名称

<!-- last-commit: 8e72ba46aec9acb2ac56f38c1783441966f16f9a -->

## [1.0.6] - 2026-02-18

修复 BSC 转账广播链路并透传 tokenAddress
Expand Down
4 changes: 2 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
"author": [
"@bfmeta.info"
],
"version": "1.0.6",
"change_log": "修复 BSC 转账广播链路并透传 tokenAddress",
"version": "1.0.7",
"change_log": "修复钱包列表链水印映射并在地址前显示链名称",
"categories": [
"application",
"wallet"
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@biochain/keyapp",
"private": true,
"version": "1.0.6",
"version": "1.0.7",
"type": "module",
"packageManager": "pnpm@10.28.0",
"scripts": {
Expand Down Expand Up @@ -218,5 +218,5 @@
"packages/*",
"miniapps/*"
],
"lastChangelogCommit": "b6845de129e00e7720e0f12402c89008b995b93f"
"lastChangelogCommit": "8e72ba46aec9acb2ac56f38c1783441966f16f9a"
}
79 changes: 41 additions & 38 deletions src/stackflow/activities/sheets/WalletListJob.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import type { ActivityComponentType } from "@stackflow/react";
import { BottomSheet } from "@/components/layout/bottom-sheet";
import { useTranslation } from "react-i18next";
import { IconPlus, IconCircleCheckFilled } from "@tabler/icons-react";
import { cn } from "@/lib/utils";
import { useFlow } from "../../stackflow";
import { useWallets, useCurrentWallet, walletActions } from "@/stores";
import { useWalletTheme } from "@/hooks/useWalletTheme";
import { useChainIconUrls } from "@/hooks/useChainIconUrls";
import { WalletMiniCard } from "@/components/wallet/wallet-mini-card";
import { useMemo } from 'react';
import type { ActivityComponentType } from '@stackflow/react';
import { BottomSheet } from '@/components/layout/bottom-sheet';
import { useTranslation } from 'react-i18next';
import { IconPlus, IconCircleCheckFilled } from '@tabler/icons-react';
import { cn } from '@/lib/utils';
import { useFlow } from '../../stackflow';
import { useWallets, useCurrentWallet, useChainPreferences, useChainConfigs, walletActions } from '@/stores';
import { useWalletTheme } from '@/hooks/useWalletTheme';
import { useChainIconUrls } from '@/hooks/useChainIconUrls';
import { WalletMiniCard } from '@/components/wallet/wallet-mini-card';

export const WalletListJob: ActivityComponentType = () => {
const { t } = useTranslation(["wallet", "common"]);
const { t } = useTranslation(['wallet', 'common']);
const { pop, push } = useFlow();
const wallets = useWallets();
const currentWallet = useCurrentWallet();
const chainPreferences = useChainPreferences();
const chainConfigs = useChainConfigs();
const currentWalletId = currentWallet?.id;
const { getWalletTheme } = useWalletTheme();
const chainIconUrls = useChainIconUrls();
const chainNameMap = useMemo(() => {
return Object.fromEntries(chainConfigs.map((config) => [config.id, config.name]));
}, [chainConfigs]);

const handleSelectWallet = (walletId: string) => {
walletActions.setCurrentWallet(walletId);
Expand All @@ -25,7 +31,7 @@ export const WalletListJob: ActivityComponentType = () => {

const handleAddWallet = () => {
pop();
push("WalletAddJob", {});
push('WalletAddJob', {});
};
const handleCancel = () => {
pop();
Expand All @@ -36,71 +42,68 @@ export const WalletListJob: ActivityComponentType = () => {
<div className="bg-background rounded-t-2xl">
{/* Handle */}
<div className="flex justify-center py-3">
<div className="h-1 w-10 rounded-full bg-muted" />
<div className="bg-muted h-1 w-10 rounded-full" />
</div>

{/* Title */}
<div className="border-b border-border px-4 pb-4">
<h2 className="text-center text-lg font-semibold">{t("common:a11y.tabWallet")}</h2>
<div className="border-border border-b px-4 pb-4">
<h2 className="text-center text-lg font-semibold">{t('common:a11y.tabWallet')}</h2>
</div>

{/* Wallet List */}
<div className="max-h-[50vh] space-y-2 overflow-y-auto p-4">
{wallets.map((wallet) => {
const isActive = wallet.id === currentWalletId;
const address = wallet.chainAddresses[0]?.address;
const preferredChain = chainPreferences[wallet.id] ?? wallet.chain;
const resolvedChain = wallet.chainAddresses.some((ca) => ca.chain === preferredChain)
? preferredChain
: (wallet.chainAddresses[0]?.chain ?? wallet.chain);
const chainAddress = wallet.chainAddresses.find((ca) => ca.chain === resolvedChain);
const address = chainAddress?.address ?? wallet.address;
const chainName =
chainNameMap[resolvedChain] ?? t(`common:chains.${resolvedChain}`, { defaultValue: resolvedChain });
const displayAddress = address
? `${address.slice(0, 6)}...${address.slice(-4)}`
: "---";
? `${chainName} · ${address.slice(0, 6)}...${address.slice(-4)}`
: `${chainName} · ---`;
const themeHue = getWalletTheme(wallet.id);

return (
<button
key={wallet.id}
onClick={() => handleSelectWallet(wallet.id)}
className={cn(
"flex w-full items-center gap-3 rounded-xl p-4 transition-all",
"active:scale-[0.98]",
isActive
? "bg-primary/10 ring-2 ring-primary"
: "bg-muted/50 hover:bg-muted"
'flex w-full items-center gap-3 rounded-xl p-4 transition-all',
'active:scale-[0.98]',
isActive ? 'bg-primary/10 ring-primary ring-2' : 'bg-muted/50 hover:bg-muted',
)}
>
{/* 钱包小卡片图标 */}
<WalletMiniCard
themeHue={themeHue}
size="md"
watermarkIconUrl={chainIconUrls[wallet.chain]}
/>
<WalletMiniCard themeHue={themeHue} size="md" watermarkIconUrl={chainIconUrls[resolvedChain]} />

{/* 钱包信息 */}
<div className="min-w-0 flex-1 text-left">
<div className="flex items-center gap-2">
<span className="truncate font-medium">{wallet.name}</span>
{isActive && (
<IconCircleCheckFilled className="size-4 shrink-0 text-primary" />
)}
{isActive && <IconCircleCheckFilled className="text-primary size-4 shrink-0" />}
</div>
<p className="truncate font-mono text-xs text-muted-foreground">
{displayAddress}
</p>
<p className="text-muted-foreground truncate font-mono text-xs">{displayAddress}</p>
</div>
</button>
);
})}
</div>

{/* Add wallet button */}
<div className="border-t border-border p-4">
<div className="border-border border-t p-4">
<button
onClick={handleAddWallet}
className={cn(
"flex w-full items-center justify-center gap-2 rounded-xl p-4",
"bg-muted/50 hover:bg-muted active:bg-muted/80 transition-colors"
'flex w-full items-center justify-center gap-2 rounded-xl p-4',
'bg-muted/50 hover:bg-muted active:bg-muted/80 transition-colors',
)}
>
<IconPlus className="size-5" />
<span className="font-medium">{t("wallet:add")}</span>
<span className="font-medium">{t('wallet:add')}</span>
</button>
</div>

Expand Down