diff --git a/examples/README.md b/examples/README.md index ec50a6c..5d734f8 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,7 +8,7 @@ The `examples/` directory is a growing & living folder, and open for contributio - [ ] Watching Epoch - Clients - [x] Public (w/ HTTP, WebSocket, Fallback) - - [ ] Wallet – JSON-RPC Account (`window.fluent`) + - [x] Wallet – JSON-RPC Account (`window.fluent`) - [ ] Wallet - JSON-RPC Account (WalletConnect v2) - Contracts - [ ] Deploying diff --git a/examples/client_wallet_fluent/README.md b/examples/client_wallet_fluent/README.md new file mode 100644 index 0000000..a7b5bc9 --- /dev/null +++ b/examples/client_wallet_fluent/README.md @@ -0,0 +1,3 @@ +# Client wallet fluent Example + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github.com/iosh/cive/tree/main/examples/client_wallet_fluent) \ No newline at end of file diff --git a/examples/client_wallet_fluent/index.html b/examples/client_wallet_fluent/index.html new file mode 100644 index 0000000..34fc418 --- /dev/null +++ b/examples/client_wallet_fluent/index.html @@ -0,0 +1,14 @@ + + + + + + + +

Wallet Client Example

+
Loading...
+ + + diff --git a/examples/client_wallet_fluent/index.tsx b/examples/client_wallet_fluent/index.tsx new file mode 100644 index 0000000..41de479 --- /dev/null +++ b/examples/client_wallet_fluent/index.tsx @@ -0,0 +1,9 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './src/App' +import 'bulma/css/bulma.css' +ReactDOM.createRoot(document.getElementById('app') as HTMLElement).render( + + + , +) diff --git a/examples/client_wallet_fluent/package.json b/examples/client_wallet_fluent/package.json new file mode 100644 index 0000000..40b82b1 --- /dev/null +++ b/examples/client_wallet_fluent/package.json @@ -0,0 +1,21 @@ +{ + "name": "client_wallet_fluent", + "private": true, + "type": "module", + "scripts": { + "dev": "vite" + }, + "dependencies": { + "bulma": "^1.0.2", + "cive": "latest", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.8", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.6.2", + "vite": "^5.4.4" + } +} diff --git a/examples/client_wallet_fluent/src/App.tsx b/examples/client_wallet_fluent/src/App.tsx new file mode 100644 index 0000000..8794d50 --- /dev/null +++ b/examples/client_wallet_fluent/src/App.tsx @@ -0,0 +1,124 @@ +import { + http, + type Address, + createPublicClient, + createWalletClient, + custom, + parseCFX, + SignMessageErrorType, +} from "cive"; +import { mainnet, testnet } from "cive/chains"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import "cive/window"; +import type { SendTransactionErrorType } from "../../../src/_types/actions/wallet/sendTransaction"; + +export default function App() { + const [account, setAccount] = useState
(); + const [transaction, setTransaction] = useState(); + const [signMessage, setSignMessage] = useState(); + + const walletClient = useMemo( + () => + createWalletClient({ + chain: testnet, + transport: custom(window.fluent!), + }), + [] + ); + + const connect = useCallback(async () => { + const [address] = await walletClient.requestAddresses(); + setAccount(address); + }, [walletClient]); + + const handleSendTransaction = useCallback(async () => { + if (account) { + try { + const hash = await walletClient.sendTransaction({ + account, + to: account, + value: parseCFX("0.01"), + }); + setTransaction(`successful: ${hash}`); + } catch (error: unknown) { + const err = error as SendTransactionErrorType; + setTransaction(err.name); + } + } + }, [walletClient, account]); + + const handleSignMessage = useCallback(async () => { + if (account) { + try { + const signature = await walletClient.signMessage({ + account, + message: "hello world", + }); + setSignMessage(`successful: ${signature}`); + } catch (error: unknown) { + const err = error as SignMessageErrorType; + + setSignMessage(err.name); + } + } + }, [walletClient, account]); + + const handleSwitchChain = useCallback(async () => { + if (account) { + await walletClient.switchChain({ id: testnet.id }); + } + }, [walletClient, account]); + useEffect(() => { + window?.fluent?.on("accountsChanged", (accounts: Address[]) => { + if (accounts.length > 0) { + setAccount(accounts[0]); + } else { + setAccount(undefined); + } + }); + window?.fluent?.on("disconnect", () => setAccount(undefined)); + }, []); + + return ( +
+
+
+ {account ? ( +
+ Account: {account} +
+
+ + result: {transaction} +
+
+ +
+
+ +
+
+ +
+
+ + result: {signMessage} +
+
+
+ ) : ( + + )} +
+
+
+ ); +} diff --git a/examples/client_wallet_fluent/tsconfig.json b/examples/client_wallet_fluent/tsconfig.json new file mode 100644 index 0000000..f0a2350 --- /dev/null +++ b/examples/client_wallet_fluent/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/examples/client_wallet_fluent/vite.config.ts b/examples/client_wallet_fluent/vite.config.ts new file mode 100644 index 0000000..36f7f4e --- /dev/null +++ b/examples/client_wallet_fluent/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 64a8aaa..005b6e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,6 +109,37 @@ importers: specifier: ^5.4.4 version: 5.4.4(@types/node@20.14.10) + examples/client_wallet_fluent: + dependencies: + bulma: + specifier: ^1.0.2 + version: 1.0.2 + cive: + specifier: latest + version: 0.4.0(typescript@5.6.2)(zod@3.23.8) + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@types/react': + specifier: ^18.3.8 + version: 18.3.8 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.3.1 + version: 4.3.1(vite@5.4.4(@types/node@20.14.10)) + typescript: + specifier: ^5.6.2 + version: 5.6.2 + vite: + specifier: ^5.4.4 + version: 5.4.4(@types/node@20.14.10) + site: dependencies: '@types/react':