TITLE: Implementing Wallet Connection Hook with Lumos and Wagmi (TSX) DESCRIPTION: Defines a React hook `useWallet` to manage wallet connection state, retrieve the connected Ethereum address, derive the corresponding CKB lock script and address using Lumos, fetch the CKB balance, and provide functions for connecting and disconnecting the wallet. It depends on `@ckb-lumos/lumos`, `react`, `wagmi`, and a local `getCapacities` utility. SOURCE: https://github.com/sporeprotocol/spore-docs/blob/main/docs/tutorials/create-on-chain-blog/create-new-site.mdx#_snippet_0 LANGUAGE: TSX CODE: ``` import { BI, commons, config, helpers } from '@ckb-lumos/lumos'; import { useEffect, useMemo, useState } from 'react'; import { useAccount, useConnect, useDisconnect } from 'wagmi'; import { InjectedConnector } from 'wagmi/connectors/injected'; import { getCapacities } from '@/utils/balance'; export default function useWallet() { const { address: ethAddress, isConnected } = useAccount(); const { connect } = useConnect({ connector: new InjectedConnector(), }); const { disconnect } = useDisconnect(); const [balance, setBalance] = useState(null); const lock = useMemo(() => { if (!ethAddress) return; return commons.omnilock.createOmnilockScript( { auth: { flag: 'ETHEREUM', content: ethAddress ?? '0x' }, }, { config: config.predefined.AGGRON4 }, ); }, [ethAddress]); const address = useMemo( () => lock ? helpers.encodeToAddress(lock, { config: config.predefined.AGGRON4, }) : undefined, [lock], ); useEffect(() => { if (!address) { return; } getCapacities(address).then((capacities) => { setBalance(capacities.div(10 ** 8)); }); }, [address]); return { address, lock, balance, isConnected, connect, disconnect, }; } ``` ---------------------------------------- TITLE: Initializing Wagmi Configuration (TypeScript/TSX) DESCRIPTION: Include this code in your `src/pages/_app.tsx` file to initialize the Wagmi configuration. It sets up auto-connection and configures a public client using `viem` to interact with the Ethereum mainnet. SOURCE: https://github.com/sporeprotocol/spore-docs/blob/main/docs/tutorials/create-on-chain-blog/connect-wallet.mdx#_snippet_1 LANGUAGE: TypeScript CODE: ``` import type { AppProps } from 'next/app'; import { WagmiConfig, createConfig, mainnet } from 'wagmi'; import { createPublicClient, http } from 'viem'; const config = createConfig({ autoConnect: true, publicClient: createPublicClient({ chain: mainnet, transport: http(), }), }); export default function App({ Component, pageProps }: AppProps) { return ( ); } ``` ---------------------------------------- TITLE: Connecting and Displaying MetaMask Address (TypeScript/TSX) DESCRIPTION: Add this code to your `src/pages/index.tsx` to implement the wallet connection logic. It uses Wagmi hooks to connect to MetaMask via `InjectedConnector`, displays the connected ETH address, and provides buttons for connecting and disconnecting. SOURCE: https://github.com/sporeprotocol/spore-docs/blob/main/docs/tutorials/create-on-chain-blog/connect-wallet.mdx#_snippet_2 LANGUAGE: TypeScript CODE: ``` import { useAccount, useConnect, useDisconnect } from 'wagmi'; import { InjectedConnector } from 'wagmi/connectors/injected'; export default function Home() { const { address, isConnected } = useAccount(); const { connect } = useConnect({ connector: new InjectedConnector(), }); const { disconnect } = useDisconnect(); return (
{address}
{isConnected ? ( ) : ( )}
); } ``` ---------------------------------------- TITLE: Creating Spore Post Transaction with Spore SDK TSX DESCRIPTION: This snippet defines a React component that handles the creation and publishing of a blog post as a Spore cell. It uses the Spore SDK's `createSpore` function to build the transaction, signs it using a wallet hook, and sends it to the CKB blockchain. The post content (title and body) is saved as a JSON string within the Spore's content field. SOURCE: https://github.com/sporeprotocol/spore-docs/blob/main/docs/tutorials/create-on-chain-blog/manage-blog-post.mdx#_snippet_0 LANGUAGE: TSX CODE: ``` import useWallet from '@/hooks/useWallet'; import { signTransaction } from '@/utils/transaction'; import { RPC } from '@ckb-lumos/lumos'; import { createSpore } from '@spore-sdk/core'; import { useRouter } from 'next/router'; import { useState } from 'react'; import { config } from '@/config'; export default function NewPost() { const router = useRouter(); const { id } = router.query; const { address, lock, isConnected, connect } = useWallet(); const [title, setTitle] = useState(''); const [content, setContent] = useState(''); const handlePublishPost = async (e: React.FormEvent) => { e.preventDefault(); if (!address || !lock) return; const { txSkeleton } = await createSpore({ data: { content: Buffer.from(JSON.stringify({ title, content })), contentType: 'application/json', clusterId: id as string, }, fromInfos: [address], toLock: lock, }); const tx = await signTransaction(txSkeleton); const rpc = new RPC(config.ckbNodeUrl); const hash = await rpc.sendTransaction(tx, 'passthrough'); setTitle(''); setContent(''); console.log(hash); }; return (
{isConnected ? (
setTitle(e.target.value)} />