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: 4 additions & 2 deletions examples/demo-general/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@
"framer-motion": "^10.18.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-hot-toast": "^2.6.0",
"react-toastify": "^10.0.6",
"react-use": "^17.6.0",
"sonner": "^2.0.7",
"typink": "workspace:*"
},
"devDependencies": {
"@dedot/chaintypes": "^0.132.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react": "^4.3.4",
Expand Down
64 changes: 49 additions & 15 deletions examples/demo-general/src/components/RemarkTransactionExample.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
import { Button, VStack, Input, Heading, Text, Spinner, Box, Flex } from '@chakra-ui/react';
import { useState } from 'react';
import { Box, Button, Flex, Heading, Input, Select, Spinner, Text, VStack } from '@chakra-ui/react';
import { useEffect, useState } from 'react';
import { useDebounce } from 'react-use';
import { useTypink, useTx, useTxFee, formatBalance } from 'typink';
import { txToaster } from '@/utils/txToaster.tsx';
import { formatBalance, setupTxToaster, txToaster, useTx, useTxFee, useTypink } from 'typink';
import { getToastAdapter, toastLibraries, type ToastLibrary } from '@/utils/toastLibraries';
import { PolkadotApi } from '@dedot/chaintypes';

export default function RemarkTransactionExample() {
const { client, connectedAccount, network } = useTypink<PolkadotApi>();
const [message, setMessage] = useState('Hello from Typink!');
const [selectedLibrary, setSelectedLibrary] = useState<ToastLibrary>('sonner');

// Debounce message changes to avoid excessive fee calculations
const [debouncedMessage, setDebouncedMessage] = useState(message);
useDebounce(() => setDebouncedMessage(message), 500, [message]);

// Setup the selected toast library whenever it changes
useEffect(() => {
const adapter = getToastAdapter(selectedLibrary);
setupTxToaster({
adapter,
initialMessage: 'Submitting transaction...',
autoCloseDelay: 5000,
messages: {
inProgress: 'Transaction In Progress...',
successful: 'Transaction Successful',
failed: 'Transaction Failed',
},
});
}, [selectedLibrary]);

// Create remarkTx for signing and sending
const remarkTx = useTx((tx) => tx.system.remark);

Expand Down Expand Up @@ -49,10 +65,10 @@ export default function RemarkTransactionExample() {
};

return (
<VStack spacing={4} align='stretch' maxW='400px' mx='auto'>
<Heading size='md'>Send System Remark</Heading>
<VStack spacing={4} align='stretch' maxW='500px' mx='auto'>
<Heading size='md'>Send System Remark with Toast Libraries</Heading>
<Text fontSize='sm' color='gray.600'>
Submit a remark transaction to the blockchain with your custom message.
Submit a remark transaction and see toast notifications using different libraries.
</Text>

<Input
Expand Down Expand Up @@ -94,14 +110,32 @@ export default function RemarkTransactionExample() {
</Flex>
)}

<Button
colorScheme='blue'
onClick={handleSendRemark}
isLoading={remarkTx.inBestBlockProgress}
isDisabled={!client || !connectedAccount || !message.trim() || remarkTx.inBestBlockProgress}
loadingText='Sending...'>
Send Remark Transaction
</Button>
{/* Toast Library Selector and Send Button Row */}
<Flex gap={3} align='center'>
<Select
value={selectedLibrary}
onChange={(e) => setSelectedLibrary(e.target.value as ToastLibrary)}
size='sm'
width='40%'
bg='white'>
{toastLibraries.map((lib) => (
<option key={lib.id} value={lib.id}>
{lib.name}
</option>
))}
</Select>

<Button
colorScheme='blue'
onClick={handleSendRemark}
isLoading={remarkTx.inBestBlockProgress}
isDisabled={!client || !connectedAccount || !message.trim() || remarkTx.inBestBlockProgress}
loadingText='Sending...'
flex={1}
size='sm'>
Send Remark Transaction
</Button>
</Flex>

{!connectedAccount && (
<Text fontSize='sm' color='orange.600' textAlign='center'>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Button, VStack, Input, Heading, Text, Spinner, Box, Flex } from '@chakra-ui/react';
import { useState } from 'react';
import { useDebounce } from 'react-use';
import { useTypink, useTx, useTxFee, useBalance, formatBalance } from 'typink';
import { txToaster } from '@/utils/txToaster.tsx';
import { useTypink, useTx, useTxFee, useBalance, formatBalance, txToaster } from 'typink';
import { PolkadotApi } from '@dedot/chaintypes';
import RecipientSelector from './RecipientSelector';

Expand Down
8 changes: 8 additions & 0 deletions examples/demo-general/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ChakraProvider } from '@chakra-ui/react';
import ReactDOM from 'react-dom/client';
import { ToastContainer } from 'react-toastify';
import { Toaster as SonnerToaster } from 'sonner';
import { Toaster as HotToastToaster } from 'react-hot-toast';
import 'react-toastify/dist/ReactToastify.css';
import App from '@/App';
import { theme } from '@/theme';
Expand Down Expand Up @@ -75,6 +77,8 @@ function Root() {
cacheMetadata={true}
wallets={[subwallet, talisman, polkadotjs]}>
<App />

{/* Toast Providers for all libraries */}
<ToastContainer
position='top-right'
closeOnClick
Expand All @@ -84,6 +88,10 @@ function Root() {
hideProgressBar
limit={10}
/>
{/* @ts-ignore */}
<SonnerToaster position='top-right' expand={false} richColors closeButton={true} />
{/* @ts-ignore */}
<HotToastToaster position='top-right' gutter={8} />
</TypinkProvider>
</ChakraProvider>
);
Expand Down
45 changes: 45 additions & 0 deletions examples/demo-general/src/utils/toastLibraries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { toast as sonnerToast } from 'sonner';
import { toast as toastifyToast } from 'react-toastify';
import { toast as hotToast } from 'react-hot-toast';
import { SonnerAdapter, ReactToastifyAdapter, ReactHotToastAdapter, ToastAdapter } from 'typink';

export type ToastLibrary = 'sonner' | 'react-toastify' | 'react-hot-toast';

export interface ToastLibraryConfig {
id: ToastLibrary;
name: string;
adapter: ToastAdapter;
}

// Create adapter instances
const sonnerAdapter = new SonnerAdapter(sonnerToast);
const toastifyAdapter = new ReactToastifyAdapter(toastifyToast);
const hotToastAdapter = new ReactHotToastAdapter(hotToast);

// Toast library configurations
export const toastLibraries: ToastLibraryConfig[] = [
{
id: 'sonner',
name: 'Sonner',
adapter: sonnerAdapter,
},
{
id: 'react-toastify',
name: 'React-Toastify',
adapter: toastifyAdapter,
},
{
id: 'react-hot-toast',
name: 'React-Hot-Toast',
adapter: hotToastAdapter,
},
];

// Helper function to get adapter by library ID
export function getToastAdapter(libraryId: ToastLibrary): ToastAdapter {
const config = toastLibraries.find((lib) => lib.id === libraryId);
if (!config) {
throw new Error(`Toast library "${libraryId}" not found`);
}
return config.adapter;
}
131 changes: 0 additions & 131 deletions examples/demo-general/src/utils/txToaster.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions examples/demo-inkv5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
},
"devDependencies": {
"@dedot/chaintypes": "^0.132.0",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vitejs/plugin-react": "^4.3.4",
Expand Down
10 changes: 5 additions & 5 deletions examples/demo-inkv5/src/components/ContractDeployerBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ import {
Thead,
Tr,
} from '@chakra-ui/react';
import { SubstrateAddress, useDeployer, useDeployerTx } from 'typink';
import { SubstrateAddress, txToaster, useDeployer, useDeployerTx } from 'typink';
import { greeterMetadata } from '@/contracts/deployments.ts';
import { GreeterContractApi } from '@/contracts/types/greeter';
import { useState } from 'react';
import { txToaster } from '@/utils/txToaster.tsx';
import { numberToHex } from 'dedot/utils';
import { useLocalStorage } from 'react-use';

Expand All @@ -43,7 +42,8 @@ export function ContractDeployerBoard() {
await newGreeterTx.signAndSend({
args: [initMessage],
txOptions: { salt },
callback: ({ status }, contractAddress) => {
callback: (progress, contractAddress) => {
const { status } = progress;
console.log(status);

if (status.type === 'BestChainBlockIncluded') {
Expand All @@ -56,12 +56,12 @@ export function ContractDeployerBoard() {
setDeployedContracts((prev) => [{ address: contractAddress, at: Date.now() }, ...(prev || [])]);
}

toaster.updateTxStatus(status);
toaster.onTxProgress(progress);
},
});
} catch (e: any) {
console.error(e);
toaster.onError(e);
toaster.onTxError(e);
}
};

Expand Down
Loading