mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-03-17 13:21:44 +01:00
show incorrect wallet balance
This commit is contained in:
parent
707d7b250a
commit
dc138f6037
106
pnpm-lock.yaml
generated
106
pnpm-lock.yaml
generated
@ -104,31 +104,31 @@ importers:
|
||||
version: 0.7.2
|
||||
applesauce-accounts:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-content:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-core:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-factory:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-loaders:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-react:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(react-dom@19.0.0(react@19.0.0))(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(react-dom@19.0.0(react@19.0.0))(typescript@5.8.2)
|
||||
applesauce-relay:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-signers:
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-wallet:
|
||||
specifier: 0.0.0-next-20250309231023
|
||||
version: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
specifier: next
|
||||
version: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
bech32:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
@ -2195,32 +2195,32 @@ packages:
|
||||
engines: {node: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
applesauce-accounts@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-7oOZ7AQ667VncranhPI1oowec2uHshq4JLdNzp6PlQq2L6/aZoCdOHrXa+mJ6V6YWRQsq1ekvqRIHEpZ0cKFfA==}
|
||||
applesauce-accounts@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-Q1vEjYznvkxRDM2C/gN+UJpjva2QvFLrIlfMTyrfm7s1nDEIKP6wJ4Oj72PsnyZREP0/UnH7fP5olvJMakBOBg==}
|
||||
|
||||
applesauce-content@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-8MigSRS3hG1/93TxBOGWpRaDoIXycnR44NbGirOYX4NG7r3UjcGMgQ1O8hG2XAz3+RKsOA3umj/0FRO7j+JgmQ==}
|
||||
applesauce-content@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-oxMgVy1hS0ZWGL+0Skrt25vcMUwY8T3A1p45vc1q17oXWbIKBqZPtenoHarluEBdY9iUt0QBVVIFWSQtphudxw==}
|
||||
|
||||
applesauce-core@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-QG0PT88QIkjbHWuJ+a3B3KEIJdKcCaPEHvYqXPbCiY73K37j5W1xVQByn2kOP8yHDk//ZOyBjrN8EsnWLSnxPg==}
|
||||
applesauce-core@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-u6YNDyPy2v+B8Iv6WFkTTnilLJfNgFVeDs+aGy4KpItq0tdEQcnwTIFRcTovSaCNn2YYNJ1WHw30/a622SmshA==}
|
||||
|
||||
applesauce-factory@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-PzFFXZgMs9q6LCP0zvUO0k6+3x5zUrtImFABBmOxsCFzMkU6a0h7SEhs8fJIXDtAz0weeC40rhyYRUWgR8jeSA==}
|
||||
applesauce-factory@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-rJNnwwxIdX1s4vdmAmIDvappQT/0J0XH+xIpMDnuf1yvMmwK/lH+DvGWPdC2h/TNI4Lbd3c3774jUkgBZoKMrQ==}
|
||||
|
||||
applesauce-loaders@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-c5RsCyOIpMKv3CKqgi7QCO7Blx6D1EZnaAfoitmqtWf7IfR50uEie3/R4myMxOjWVZa4I6bqWQba+Imqfpg8PQ==}
|
||||
applesauce-loaders@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-KiqVGqzIEOuGfLU6TGGjRFru7/0e1HATSyWsXyvyPJd0Pt5Ud9tkJidI+bAY+jZthDcBlFdEPT4HTPjKJ63AOg==}
|
||||
|
||||
applesauce-react@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-WEw6ykfnghhwK22kziRoSISfpXpeMF9gzT0Khe/ZaSs+U/qVVml62TlKeVuYn0u95SlrMHrSB/OmkDSj8koNWw==}
|
||||
applesauce-react@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-MrWVYJUuKGAuW0ZjUTBgNP/o4AVth1vPlmAra0xYsH5y8puQvU0APqXpH60yrOGqMvtWiZbpMpnhPKjmjytxfw==}
|
||||
|
||||
applesauce-relay@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-ga3fLhqu4RVZQkf6xM/Y/gCIg+pzw6s17PQczLtE+k+Iz5utHk0dpOAHChoA94xMt1je3U1MZbnmZUmzD3lf0A==}
|
||||
applesauce-relay@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-5QyyRQc5vEHGUWJgHRw6hM5zSkvkqt+UYrwkL9yGcP1rQ/IyM0kcoog1VobKrSGjlQOyXxhw0cShSKoTzGWreA==}
|
||||
|
||||
applesauce-signers@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-FOsD05Ymj9pNPj4LvC4xy3L3z9CKZT6LlbkEbAltw/YMubcEuqALZH9dCY69D7xiUUJvk0HqDpfDyq+iXmiiFA==}
|
||||
applesauce-signers@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-dfppzzFIT3FtLF9JmBNAQToD8euOsWqt940itYMvesP5gV7BEHCSPiBzHdaXPNfK5/ay/kN9WHleBdwVcKTW5A==}
|
||||
|
||||
applesauce-wallet@0.0.0-next-20250309231023:
|
||||
resolution: {integrity: sha512-QxdomzWOMd/x6ip3cxrT6jXqcLUPfBb31vafTDDJM5cCNVby4IElUyZCIh0SWEdauK53xv7dkOYrsWzpKDL/4w==}
|
||||
applesauce-wallet@0.0.0-next-20250310121307:
|
||||
resolution: {integrity: sha512-9rwmR4RsJ1hv5nM7uOo/HWKHzhkhuueEtL99ZJleOGnQWm6fTz0LlMRDCT8OLlX7ZCC9Oho7p38YBqISQzJHew==}
|
||||
|
||||
arg@4.1.3:
|
||||
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
|
||||
@ -3036,8 +3036,8 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
hasBin: true
|
||||
|
||||
electron-to-chromium@1.5.113:
|
||||
resolution: {integrity: sha512-wjT2O4hX+wdWPJ76gWSkMhcHAV2PTMX+QetUCPYEdCIe+cxmgzzSSiGRCKW8nuh4mwKZlpv0xvoW7OF2X+wmHg==}
|
||||
electron-to-chromium@1.5.114:
|
||||
resolution: {integrity: sha512-DFptFef3iktoKlFQK/afbo274/XNWD00Am0xa7M8FZUepHlHT8PEuiNBoRfFHbH1okqN58AlhbJ4QTkcnXorjA==}
|
||||
|
||||
elementtree@0.1.7:
|
||||
resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==}
|
||||
@ -8435,10 +8435,10 @@ snapshots:
|
||||
dependencies:
|
||||
entities: 2.2.0
|
||||
|
||||
applesauce-accounts@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-accounts@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.1
|
||||
applesauce-signers: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-signers: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
nanoid: 5.1.3
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
rxjs: 7.8.2
|
||||
@ -8446,13 +8446,13 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-content@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-content@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
'@cashu/cashu-ts': 2.0.0-rc1
|
||||
'@types/hast': 3.0.4
|
||||
'@types/mdast': 4.0.4
|
||||
'@types/unist': 3.0.3
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
mdast-util-find-and-replace: 3.0.2
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
remark: 15.0.1
|
||||
@ -8463,7 +8463,7 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-core@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-core@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.1
|
||||
'@scure/base': 1.2.4
|
||||
@ -8478,19 +8478,19 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-factory@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-factory@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
applesauce-content: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-content: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
nanoid: 5.1.3
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-loaders@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-loaders@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
nanoid: 5.1.3
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
rx-nostr: 3.5.0
|
||||
@ -8499,12 +8499,12 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-react@0.0.0-next-20250309231023(react-dom@19.0.0(react@19.0.0))(typescript@5.8.2):
|
||||
applesauce-react@0.0.0-next-20250310121307(react-dom@19.0.0(react@19.0.0))(typescript@5.8.2):
|
||||
dependencies:
|
||||
applesauce-accounts: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-content: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-factory: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-accounts: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-content: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
applesauce-factory: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
observable-hooks: 4.2.4(react-dom@19.0.0(react@19.0.0))(react@18.3.1)(rxjs@7.8.2)
|
||||
react: 18.3.1
|
||||
@ -8514,9 +8514,9 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-relay@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-relay@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
nanoid: 5.1.3
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
rxjs: 7.8.2
|
||||
@ -8524,12 +8524,12 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-signers@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-signers@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
'@noble/hashes': 1.7.1
|
||||
'@noble/secp256k1': 1.7.1
|
||||
'@scure/base': 1.2.4
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
debug: 4.4.0
|
||||
nanoid: 5.1.3
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
@ -8537,9 +8537,9 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
applesauce-wallet@0.0.0-next-20250309231023(typescript@5.8.2):
|
||||
applesauce-wallet@0.0.0-next-20250310121307(typescript@5.8.2):
|
||||
dependencies:
|
||||
applesauce-core: 0.0.0-next-20250309231023(typescript@5.8.2)
|
||||
applesauce-core: 0.0.0-next-20250310121307(typescript@5.8.2)
|
||||
nostr-tools: 2.10.4(typescript@5.8.2)
|
||||
rxjs: 7.8.2
|
||||
transitivePeerDependencies:
|
||||
@ -8763,7 +8763,7 @@ snapshots:
|
||||
browserslist@4.24.4:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001703
|
||||
electron-to-chromium: 1.5.113
|
||||
electron-to-chromium: 1.5.114
|
||||
node-releases: 2.0.19
|
||||
update-browserslist-db: 1.1.3(browserslist@4.24.4)
|
||||
|
||||
@ -9460,7 +9460,7 @@ snapshots:
|
||||
dependencies:
|
||||
jake: 10.9.2
|
||||
|
||||
electron-to-chromium@1.5.113: {}
|
||||
electron-to-chromium@1.5.114: {}
|
||||
|
||||
elementtree@0.1.7:
|
||||
dependencies:
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { eventStore } from "../services/event-store";
|
||||
import useForceUpdate from "./use-force-update";
|
||||
|
||||
export default function useEventUpdate(id?: string) {
|
||||
const [_count, setCount] = useState(0);
|
||||
const update = useForceUpdate();
|
||||
|
||||
const observable = useMemo(() => (id ? eventStore.event(id) : undefined), [id]);
|
||||
const observable = useMemo(() => (id ? eventStore.updated(id) : undefined), [id]);
|
||||
useEffect(() => {
|
||||
if (!observable) return;
|
||||
const sub = observable.subscribe(() => setCount((v) => v + 1));
|
||||
const sub = observable.subscribe(update);
|
||||
return () => sub.unsubscribe();
|
||||
}, [observable]);
|
||||
}, [observable, update]);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
export default function useForceUpdate() {
|
||||
const [count, setCount] = useState(0);
|
||||
const [_count, setCount] = useState(0);
|
||||
const update = useCallback(() => {
|
||||
setCount((v) => v + 1);
|
||||
}, [setCount]);
|
||||
|
44
src/views/wallet/balance-card.tsx
Normal file
44
src/views/wallet/balance-card.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import { Button, Card, CardBody, CardFooter, CardHeader, CardProps, Text } from "@chakra-ui/react";
|
||||
import { useActiveAccount, useEventStore, useStoreQuery } from "applesauce-react/hooks";
|
||||
import { WalletBalanceQuery } from "applesauce-wallet/queries";
|
||||
import { ECashIcon } from "../../components/icons";
|
||||
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
||||
import { isWalletLocked, unlockWallet, WALLET_KIND } from "applesauce-wallet/helpers";
|
||||
import useAsyncErrorHandler from "../../hooks/use-async-error-handler";
|
||||
import useEventUpdate from "../../hooks/use-event-update";
|
||||
|
||||
export default function WalletBalanceCard({ pubkey, ...props }: { pubkey: string } & Omit<CardProps, "children">) {
|
||||
const account = useActiveAccount();
|
||||
const eventStore = useEventStore();
|
||||
const wallet = useReplaceableEvent({ kind: WALLET_KIND, pubkey });
|
||||
useEventUpdate(wallet?.id);
|
||||
|
||||
const locked = !wallet || isWalletLocked(wallet);
|
||||
const balance = useStoreQuery(WalletBalanceQuery, [pubkey]);
|
||||
|
||||
const unlock = useAsyncErrorHandler(async () => {
|
||||
if (!account) throw new Error("Missing account");
|
||||
if (!wallet) throw new Error("Missing wallet");
|
||||
await unlockWallet(wallet, account);
|
||||
eventStore.update(wallet);
|
||||
}, [wallet, account]);
|
||||
|
||||
return (
|
||||
<Card {...props}>
|
||||
<CardHeader gap="2" display="flex" justifyContent="center" alignItems="center" pt="10">
|
||||
<ECashIcon color="green.400" boxSize={6} />
|
||||
<Text fontWeight="bold" fontSize="lg">
|
||||
{balance ? Object.values(balance).reduce((t, v) => t + v, 0) : "--Locked--"}
|
||||
</Text>
|
||||
</CardHeader>
|
||||
<CardBody></CardBody>
|
||||
{locked && (
|
||||
<CardFooter display="flex">
|
||||
<Button colorScheme="primary" onClick={unlock} mx="auto">
|
||||
Unlock
|
||||
</Button>
|
||||
</CardFooter>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
@ -1,46 +1,68 @@
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
AlertIcon,
|
||||
AlertTitle,
|
||||
Badge,
|
||||
Button,
|
||||
Card,
|
||||
CardBody,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
Flex,
|
||||
Heading,
|
||||
Spinner,
|
||||
} from "@chakra-ui/react";
|
||||
import { NostrEvent } from "nostr-tools";
|
||||
import { Button, ButtonGroup, Card, CardBody, CardFooter, Flex, Text } from "@chakra-ui/react";
|
||||
import { kinds, NostrEvent } from "nostr-tools";
|
||||
import { WalletQuery } from "applesauce-wallet/queries";
|
||||
import { unlockWallet, WALLET_KIND } from "applesauce-wallet/helpers";
|
||||
import {
|
||||
getTokenDetails,
|
||||
isTokenDetailsLocked,
|
||||
unlockTokenDetails,
|
||||
unlockWallet,
|
||||
WALLET_KIND,
|
||||
WALLET_TOKEN_KIND,
|
||||
} from "applesauce-wallet/helpers";
|
||||
|
||||
import { useActiveAccount, useStoreQuery } from "applesauce-react/hooks";
|
||||
import { useActiveAccount, useEventStore, useStoreQuery } from "applesauce-react/hooks";
|
||||
import useAsyncErrorHandler from "../../hooks/use-async-error-handler";
|
||||
import DebugEventButton from "../../components/debug-modal/debug-event-button";
|
||||
import { eventStore } from "../../services/event-store";
|
||||
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
||||
import SimpleView from "../../components/layout/presets/simple-view";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import useUserMailboxes from "../../hooks/use-user-mailboxes";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import useEventIntersectionRef from "../../hooks/use-event-intersection-ref";
|
||||
import useEventUpdate from "../../hooks/use-event-update";
|
||||
import DebugEventButton from "../../components/debug-modal/debug-event-button";
|
||||
import { ECashIcon } from "../../components/icons";
|
||||
import WalletBalanceCard from "./balance-card";
|
||||
import { useMemo } from "react";
|
||||
|
||||
function Wallet({ wallet }: { wallet: NostrEvent }) {
|
||||
const account = useActiveAccount()!;
|
||||
function TokenEvent({ token }: { token: NostrEvent }) {
|
||||
const account = useActiveAccount();
|
||||
const eventStore = useEventStore();
|
||||
useEventUpdate(token.id);
|
||||
const ref = useEventIntersectionRef(token);
|
||||
|
||||
const walletInfo = useStoreQuery(WalletQuery, [account.pubkey]);
|
||||
const locked = isTokenDetailsLocked(token);
|
||||
const details = !locked ? getTokenDetails(token) : undefined;
|
||||
const amount = details?.proofs.reduce((t, p) => t + p.amount, 0);
|
||||
|
||||
const unlock = useAsyncErrorHandler(async () => {
|
||||
if (!account) return;
|
||||
await unlockTokenDetails(token, account);
|
||||
eventStore.update(token);
|
||||
}, [token, account, eventStore]);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader display="flex" gap="2" p="2" alignItems="center">
|
||||
<Heading size="md">Wallet</Heading>
|
||||
{walletInfo?.locked && <Badge colorScheme="orange">Locked</Badge>}
|
||||
{wallet && <DebugEventButton event={wallet} variant="ghost" ml="auto" size="sm" />}
|
||||
</CardHeader>
|
||||
{walletInfo?.locked === false && (
|
||||
<CardBody px="2" py="0" whiteSpace="pre-line">
|
||||
Key: {walletInfo.privateKey}
|
||||
Mints: {walletInfo.mints.join(", ")}
|
||||
</CardBody>
|
||||
<Card ref={ref} w="full">
|
||||
<CardBody p="2" alignItems="center" flexDirection="row" display="flex" gap="2">
|
||||
<ECashIcon color="green.400" boxSize={6} />
|
||||
{amount && <Text>{amount}</Text>}
|
||||
<ButtonGroup size="sm" ms="auto">
|
||||
{locked && (
|
||||
<Button onClick={unlock} variant="link" p="2">
|
||||
Unlock
|
||||
</Button>
|
||||
)}
|
||||
<DebugEventButton variant="ghost" event={token} />
|
||||
</ButtonGroup>
|
||||
</CardBody>
|
||||
{details && (
|
||||
<CardFooter px="2" pt="0" pb="0">
|
||||
<Text fontSize="sm" fontStyle="italic">
|
||||
{details.mint}
|
||||
</Text>
|
||||
</CardFooter>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
@ -50,56 +72,61 @@ export default function WalletHomeView() {
|
||||
const account = useActiveAccount()!;
|
||||
const wallet = useReplaceableEvent({ kind: WALLET_KIND, pubkey: account.pubkey });
|
||||
|
||||
const mailboxes = useUserMailboxes(account.pubkey);
|
||||
const readRelays = useReadRelays(mailboxes?.outboxes);
|
||||
const { timeline: events, loader } = useTimelineLoader(`${account.pubkey}-wallet-tokens`, readRelays, [
|
||||
{
|
||||
kinds: [WALLET_TOKEN_KIND],
|
||||
authors: [account.pubkey],
|
||||
},
|
||||
{ kinds: [kinds.EventDeletion], "#k": [String(WALLET_TOKEN_KIND)], authors: [account.pubkey] },
|
||||
]);
|
||||
|
||||
const tokens = useMemo(() => events.filter((e) => e.kind === WALLET_TOKEN_KIND), [events]);
|
||||
|
||||
const unlock = useAsyncErrorHandler(async () => {
|
||||
if (!wallet) throw new Error("Missing wallet");
|
||||
await unlockWallet(wallet, account);
|
||||
eventStore.update(wallet);
|
||||
}, [wallet, account]);
|
||||
|
||||
// attempt to unlock all tokens
|
||||
for (const token of tokens) {
|
||||
await unlockTokenDetails(token, account);
|
||||
eventStore.update(token);
|
||||
}
|
||||
}, [wallet, account, tokens]);
|
||||
|
||||
const walletInfo = useStoreQuery(WalletQuery, [account.pubkey]);
|
||||
|
||||
const callback = useTimelineCurserIntersectionCallback(loader);
|
||||
|
||||
return (
|
||||
<SimpleView
|
||||
title="Wallet"
|
||||
actions={
|
||||
walletInfo?.locked && (
|
||||
<Button onClick={unlock} colorScheme="primary" ms="auto" size="sm">
|
||||
Unlock
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
>
|
||||
{walletInfo?.locked && (
|
||||
<Alert
|
||||
status="info"
|
||||
variant="subtle"
|
||||
flexDirection="column"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
textAlign="center"
|
||||
height="xs"
|
||||
maxW="2xl"
|
||||
mx="auto"
|
||||
>
|
||||
<AlertIcon boxSize="40px" mr={0} />
|
||||
<AlertTitle mt={4} mb={1} fontSize="lg">
|
||||
Wallet locked!
|
||||
</AlertTitle>
|
||||
<AlertDescription maxWidth="sm">
|
||||
Your wallet is locked, you need to unlock it in order to use it
|
||||
</AlertDescription>
|
||||
<Button onClick={unlock} colorScheme="primary" mt="6">
|
||||
Unlock
|
||||
</Button>
|
||||
</Alert>
|
||||
)}
|
||||
{walletInfo?.locked === false && (
|
||||
<Card p="2" whiteSpace="pre-line">
|
||||
Key: {walletInfo.privateKey}
|
||||
<br />
|
||||
Mints: {walletInfo.mints.join(", ")}
|
||||
</Card>
|
||||
)}
|
||||
</SimpleView>
|
||||
<IntersectionObserverProvider callback={callback}>
|
||||
<SimpleView
|
||||
title="Wallet"
|
||||
actions={
|
||||
walletInfo?.locked && (
|
||||
<Button onClick={unlock} colorScheme="primary" ms="auto" size="sm">
|
||||
Unlock
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
>
|
||||
<WalletBalanceCard pubkey={account.pubkey} w="full" maxW="2xl" mx="auto" />
|
||||
{walletInfo?.locked === false && (
|
||||
<Card p="2" whiteSpace="pre-line">
|
||||
Key: {walletInfo.privateKey}
|
||||
<br />
|
||||
Mints: {walletInfo.mints.join(", ")}
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<Flex direction="column" gap="2" w="full" maxW="lg" mx="auto">
|
||||
{tokens.map((token) => (
|
||||
<TokenEvent key={token.id} token={token} />
|
||||
))}
|
||||
</Flex>
|
||||
</SimpleView>
|
||||
</IntersectionObserverProvider>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user