diff --git a/.changeset/poor-ghosts-obey.md b/.changeset/poor-ghosts-obey.md
new file mode 100644
index 00000000..96bad278
--- /dev/null
+++ b/.changeset/poor-ghosts-obey.md
@@ -0,0 +1,5 @@
+---
+"@reactive-dot/utils": minor
+---
+
+Add utilities for getting the minimum and/or maximum value from a list of big integers.
diff --git a/.changeset/serious-mayflies-sneeze.md b/.changeset/serious-mayflies-sneeze.md
new file mode 100644
index 00000000..b7dcab6b
--- /dev/null
+++ b/.changeset/serious-mayflies-sneeze.md
@@ -0,0 +1,5 @@
+---
+"@reactive-dot/react": minor
+---
+
+Add hook for getting account's spendable balance.
diff --git a/apps/example/src/app.tsx b/apps/example/src/app.tsx
index 9da09f5d..e9ad367a 100644
--- a/apps/example/src/app.tsx
+++ b/apps/example/src/app.tsx
@@ -1,5 +1,10 @@
import { config } from "./config";
-import { IDLE, MutationError, PENDING } from "@reactive-dot/core";
+import {
+ IDLE,
+ MutationError,
+ PENDING,
+ type PolkadotAccount,
+} from "@reactive-dot/core";
import type { Wallet } from "@reactive-dot/core/wallets.js";
import {
ReDotChainProvider,
@@ -13,6 +18,7 @@ import {
useMutationEffect,
useNativeTokenAmountFromPlanck,
useQueryErrorResetter,
+ useSpendableBalance,
useWalletConnector,
useWalletDisconnector,
useWallets,
@@ -23,11 +29,16 @@ import { Suspense, useState, useTransition } from "react";
import { ErrorBoundary, type FallbackProps } from "react-error-boundary";
import toast, { Toaster } from "react-hot-toast";
-function PendingRewards(props: { address: string; rewards: bigint }) {
+type PendingRewardsProps = {
+ account: PolkadotAccount;
+ rewards: bigint;
+};
+
+function PendingRewards({ account, rewards }: PendingRewardsProps) {
return (
- {props.address}:{" "}
- {useNativeTokenAmountFromPlanck(props.rewards).toLocaleString()}
+ {account.name ?? account.address}:{" "}
+ {useNativeTokenAmountFromPlanck(rewards).toLocaleString()}
);
}
@@ -68,7 +79,7 @@ function PendingPoolRewards() {
))}
@@ -77,6 +88,46 @@ function PendingPoolRewards() {
);
}
+type SpendableBalanceProps = {
+ account: PolkadotAccount;
+};
+
+function SpendableBalance({ account }: SpendableBalanceProps) {
+ return (
+
+ {account.name ?? account.address}:{" "}
+ {useSpendableBalance(account.address).toLocaleString()}
+
+ );
+}
+
+function SpendableBalances() {
+ const accounts = useAccounts();
+
+ if (accounts.length === 0) {
+ return (
+
+ Balances
+ Please connect accounts to see balances
+
+ );
+ }
+
+ return (
+
+ Spendable balances
+
+ {accounts.map((account) => (
+
+ ))}
+
+
+ );
+}
+
function Query() {
const block = useBlock();
@@ -159,6 +210,7 @@ function Query() {
{x.asText()}
))}
+
);
@@ -168,16 +220,16 @@ type WalletItemProps = {
wallet: Wallet;
};
-function WalletItem(props: WalletItemProps) {
+function WalletItem({ wallet }: WalletItemProps) {
const connectedWallets = useConnectedWallets();
- const [connectingState, connect] = useWalletConnector(props.wallet);
- const [disconnectingState, disconnect] = useWalletDisconnector(props.wallet);
+ const [connectingState, connect] = useWalletConnector(wallet);
+ const [disconnectingState, disconnect] = useWalletDisconnector(wallet);
return (
- {props.wallet.name}:{" "}
- {connectedWallets.includes(props.wallet) ? (
+ {wallet.name}:{" "}
+ {connectedWallets.includes(wallet) ? (