From bec53aa2e58ff242a330b0d2ee634dd2659ea912 Mon Sep 17 00:00:00 2001 From: "zapaz.eth" Date: Sat, 28 Dec 2024 15:18:00 +0100 Subject: [PATCH] improved README --- .envrc | 13 -- .gitignore | 3 +- LICENSE | 21 +++ README.md | 144 +++++++++++++----- package.json | 3 +- src/lib/examples/Counter.svelte.ts | 20 +++ src/lib/wagmi/classes/SmartContract.svelte.ts | 3 +- src/lib/wagmi/ts/notification.ts | 2 +- src/routes/+layout.svelte | 35 +---- src/routes/+page.svelte | 11 +- src/routes/connect/+layout.svelte | 38 +++++ src/routes/{ => connect}/counter/+page.svelte | 10 +- .../{ => connect}/deployments/+page.svelte | 10 +- src/routes/counter/Counter.svelte.ts | 32 ---- src/routes/notification/+page.svelte | 9 -- src/routes/quick/counter/+page.svelte | 28 ++++ src/routes/quick/notification/+page.svelte | 23 +++ turbo.json | 43 ++++-- 18 files changed, 293 insertions(+), 155 deletions(-) delete mode 100644 .envrc create mode 100644 LICENSE create mode 100644 src/lib/examples/Counter.svelte.ts create mode 100644 src/routes/connect/+layout.svelte rename src/routes/{ => connect}/counter/+page.svelte (67%) rename src/routes/{ => connect}/deployments/+page.svelte (61%) delete mode 100644 src/routes/counter/Counter.svelte.ts delete mode 100644 src/routes/notification/+page.svelte create mode 100644 src/routes/quick/counter/+page.svelte create mode 100644 src/routes/quick/notification/+page.svelte diff --git a/.envrc b/.envrc deleted file mode 100644 index 9580819..0000000 --- a/.envrc +++ /dev/null @@ -1,13 +0,0 @@ -keys=( - ALCHEMY_API_KEY - ETHERSCAN_API_KEY - PUBLIC_WALLET_CONNECT_PROJECT_ID -) - -for key in "${keys[@]}"; do - export $key=$(getSecret $key) -done - -export PUBLIC_ALCHEMY_API_KEY=$ALCHEMY_API_KEY -export PUBLIC_BURNER_WALLET_KEY=0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba - diff --git a/.gitignore b/.gitignore index f0dacfa..1c9c4c5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,7 @@ dist Thumbs.db # Env -.env -.env.* +.env* !.env.example !.env.test diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9062476 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-2024 Kredeum + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 61880b1..ea37751 100644 --- a/README.md +++ b/README.md @@ -2,77 +2,151 @@ A Svelte 5 Web3 library based on Wagmi, providing seamless integration of Web3 functionality into your Svelte applications. -## Features +## ✨ Features -- 🔌 Built for Svelte 5 -- 🌐 Web3 Integration -- 🔒 Wallet Connection Management -- ⛓️ Multi-chain Support -- 🎣 Reactive Web3 Hooks +- 🔌 Built for Svelte 5 with full TypeScript support +- 🌐 Web3 Integration using Wagmi core functionality +- 🔒 Secure Wallet Connection Management +- ⛓️ Multi-chain Support with Auto-detection +- 🎣 Reactive Web3 Hooks for Real-time Updates - 🔄 Auto-refresh on Network Changes +- 📦 Simple and Intuitive API +- 🛠️ Type-safe Contract Interactions -## Installation +## 📁 Repository Structure + +This repository contains two main parts: + +- 📦 The Svelte5 package code in `src/lib/wagmi` +- 🎮 A SvelteKit demo app with usage examples in `src/routes` + +## 📦 Svelte5 Package + +### 💻 Installation + +Add this package to your Svelte5 project: ```bash npm install @kredeum/wagmi-svelte5 # or -pnpm add @kredeum/wagmi-svelte5 +pnpm install @kredeum/wagmi-svelte5 # or yarn add @kredeum/wagmi-svelte5 ``` -## Quick Start +### 🚀 Quick Start -```typescript -import { createConfig } from "@kredeum/wagmi-svelte5"; +#### Simple Example + +```svelte + -// Configure your Web3 settings -const config = createConfig({ - // Your configuration options here -}); +{counter.number}² = {counter.square(counter.number)} ``` -## Usage +#### Using this Counter class Helper -### Connect Wallet +```typescript +import { SmartContract } from "$lib/wagmi"; + +export class Counter extends SmartContract { + get number() { + return this.call("number") as bigint; + } + square(num: number | bigint) { + return this.call("square", [num]) as bigint; + } + constructor() { + super("Counter"); + } +} +``` + +#### Same example without Helper ```svelte - - +{num}² = {square} ``` -## Requirements +#### 📄 Smart Contract Source -- Svelte 5.x -- Node.js 16+ +```solidity +// Counter.sol +contract Counter is ICounter { + uint256 public number; -## Development + function square(uint256 num) public pure override(ICounter) returns (uint256) { + return num ** 2; + } + ... +} +``` + +Full Counter.sol code deployed on Base Sepolia testnet can be Viewed here: +🔍 [on BaseScan](https://sepolia.basescan.org/address/0xb1eC295A306436560C7A27616f51B5d76D6aDCa8#code) + +## 🎮 SvelteKit Demo and Examples + +The demo app in `src/routes` showcases various package features and usage patterns. + +### 🛠️ Requirements + +Your local machine needs: + +- 📦 [Node.js](https://nodejs.org/) 20+ +- 📦 [Pnpm](https://pnpm.io/) 9+ + +Optional but recommended: + +- 🚀 [Turborepo](https://turbo.build/repo) 1.8+ + +### ⚡ Quick Setup + +Get started with the examples: ```bash +# Clone the repository +git clone https://github.com/kredeum/wagmi-svelte5.git +cd wagmi-svelte5 + # Install dependencies pnpm install -# Run development server -pnpm dev +# Run the demo app +turbo start +# or without Turborepo +pnpx turbo start +``` -# Build package -pnpm build +🌐 Your browser will open to http://localhost:5173 showing the `Tests` page -# Run tests -pnpm test -``` +## 🤝 Contributing -## Contributing +We welcome contributions! Feel free to: -Contributions are welcome! Please feel free to submit a Pull Request. +- 🐛 Report issues +- 💡 Suggest features +- 🔧 Submit pull requests -## License +## 📄 License MIT License - see the [LICENSE](LICENSE) file for details. -## Author +## 👨‍💻 Author zapaz.eth (http://labs.kredeum.com/) diff --git a/package.json b/package.json index f61edde..b5f80e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kredeum/wagmi-svelte5", - "version": "0.1.5", + "version": "0.1.6", "type": "module", "description": "Svelte5 Web3 library based on Wagmi", "keywords": [ @@ -40,6 +40,7 @@ "build": "vite build", "test": "pnpm run test:unit && pnpm run test:e2e", "dev": "vite dev", + "start": "vite dev", "preview": "vite preview", "test:unit": "vitest run", "test:e2e": "playwright test", diff --git a/src/lib/examples/Counter.svelte.ts b/src/lib/examples/Counter.svelte.ts new file mode 100644 index 0000000..eae6f13 --- /dev/null +++ b/src/lib/examples/Counter.svelte.ts @@ -0,0 +1,20 @@ +import { SmartContract } from "$lib/wagmi"; + +class Counter extends SmartContract { + get number() { + return this.call("number") as bigint; + } + increment = async () => { + await this.sendAndWait("increment"); + await this.callAsync("number"); + }; + square(num: number | bigint) { + return this.call("square", [num || 0n]) as bigint; + } + + constructor() { + super("Counter"); + } +} + +export { Counter }; diff --git a/src/lib/wagmi/classes/SmartContract.svelte.ts b/src/lib/wagmi/classes/SmartContract.svelte.ts index 17affb2..e6b178c 100644 --- a/src/lib/wagmi/classes/SmartContract.svelte.ts +++ b/src/lib/wagmi/classes/SmartContract.svelte.ts @@ -65,8 +65,7 @@ class SmartContract { functionName: string = "", args: unknown[] = [] ) => { - // console.log("SMARTCONTRACT READ", functionName, args, chainId, deployment.address, `#${this.id}`); - // console.log("SMARTCONTRACT READ", deployment.abi); + // console.log("SMARTCONTRACT READ", functionName, args, chainId, `#${this.id}`); const abiFunction = (abi as unknown as AbiFunction[]).find( (f) => f.type === "function" && f.name === functionName && f.inputs.length === args.length ); diff --git a/src/lib/wagmi/ts/notification.ts b/src/lib/wagmi/ts/notification.ts index a5308d2..e6b9f56 100644 --- a/src/lib/wagmi/ts/notification.ts +++ b/src/lib/wagmi/ts/notification.ts @@ -53,7 +53,7 @@ export const notification = { loading: (Content: Renderable, options?: NotificationOptions) => { return Notification({ Content, status: "loading", ...options }); }, - remove: (toastId: string) => { + remove: (toastId?: string) => { toast.remove(toastId); } }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 79e59de..b9d0db8 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,19 +1,9 @@ @@ -24,27 +14,6 @@ Tests -
- {#if account.address} - {account.address} ({account.chainId}) - - - - {#each chains as chain (chain.id)} - {#if chain.id !== account.chainId} - - - - {/if} - {/each} -
- {:else} - - {/if} -
- -
{@render children()}
+ {@render children()} diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index d9dd675..0ddc604 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,11 +1,12 @@ -{#snippet pageTest(pageName: string)} -
  • {pageName}
  • +{#snippet pageTest(pagePath: string, pageDescription: string)} +
  • {pageDescription}
  • {/snippet}
      - {@render pageTest("notification")} - {@render pageTest("counter")} - {@render pageTest("deployments")} + {@render pageTest("/quick/counter", "Read Counter")} + {@render pageTest("/connect/counter", "Read/Write Counter")} + {@render pageTest("/quick/notification", "Notifications")} + {@render pageTest("/connect/deployments", "Deployments")}
    diff --git a/src/routes/connect/+layout.svelte b/src/routes/connect/+layout.svelte new file mode 100644 index 0000000..18399ce --- /dev/null +++ b/src/routes/connect/+layout.svelte @@ -0,0 +1,38 @@ + + +
    + {#if account.address} + {account.address} ({account.chainId}) + + + + {#each chains as chain (chain.id)} + {#if chain.id !== account.chainId} + + + + {/if} + {/each} +
    + {:else} + + {/if} +
    + +{@render children()} diff --git a/src/routes/counter/+page.svelte b/src/routes/connect/counter/+page.svelte similarity index 67% rename from src/routes/counter/+page.svelte rename to src/routes/connect/counter/+page.svelte index e18ac17..3a39846 100644 --- a/src/routes/counter/+page.svelte +++ b/src/routes/connect/counter/+page.svelte @@ -1,13 +1,12 @@ -
    +
    {contract.isFetching ? "fetching..." @@ -20,14 +19,9 @@ : "ok!"}
    -
    {contract.number}² = {contract.square(contract.number)}
    - -
    diff --git a/src/routes/deployments/+page.svelte b/src/routes/connect/deployments/+page.svelte similarity index 61% rename from src/routes/deployments/+page.svelte rename to src/routes/connect/deployments/+page.svelte index 7b6295d..0f1f747 100644 --- a/src/routes/deployments/+page.svelte +++ b/src/routes/connect/deployments/+page.svelte @@ -4,12 +4,12 @@ console.log("DEPLOYMENTS", deployments); -
    - Deployment Counter, address on chain #{wagmi.chainId} = - {readDeploymentByName(wagmi.chainId, "Counter")?.address} -
    +
    +
    + Deployment Counter, address on chain #{wagmi.chainId} = + {readDeploymentByName(wagmi.chainId, "Counter")?.address} +
    -
    All Deployments
    diff --git a/src/routes/counter/Counter.svelte.ts b/src/routes/counter/Counter.svelte.ts
    deleted file mode 100644
    index 8a6e9c7..0000000
    --- a/src/routes/counter/Counter.svelte.ts
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -import type { Address } from "viem";
    -import { SmartContract, isAddress } from "$lib/wagmi";
    -
    -class Counter extends SmartContract {
    -  get number() {
    -    return this.call("number") as bigint;
    -  }
    -  increment = async () => {
    -    await this.sendAndWait("increment");
    -    await this.callAsync("number");
    -  };
    -  setNumber = async (num: number | bigint = 1n) => {
    -    await this.sendAndWait("setNumber", [num]);
    -    await this.callAsync("number");
    -  };
    -  square(num: number | bigint = 1n) {
    -    return this.call("square", [num]) as bigint;
    -  }
    -  balanceOf(address: Address) {
    -    if (!isAddress(address)) return;
    -
    -    const balance = this.call("balanceOf", [address]) as bigint;
    -
    -    return balance;
    -  }
    -
    -  constructor() {
    -    super("Counter");
    -  }
    -}
    -
    -export { Counter };
    diff --git a/src/routes/notification/+page.svelte b/src/routes/notification/+page.svelte
    deleted file mode 100644
    index 8a7307a..0000000
    --- a/src/routes/notification/+page.svelte
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -
    -
    -
    - -
    diff --git a/src/routes/quick/counter/+page.svelte b/src/routes/quick/counter/+page.svelte new file mode 100644 index 0000000..e9e64cf --- /dev/null +++ b/src/routes/quick/counter/+page.svelte @@ -0,0 +1,28 @@ + + +
    + Using Counter class Helper +
    + {counter.number}² = {counter.square(counter.number)} +
    +
    + +
    + Using SmartContract class +
    + {num}² = {square} +
    +
    diff --git a/src/routes/quick/notification/+page.svelte b/src/routes/quick/notification/+page.svelte new file mode 100644 index 0000000..3e79573 --- /dev/null +++ b/src/routes/quick/notification/+page.svelte @@ -0,0 +1,23 @@ + + +
    +

    Notifications

    + + + + + + +
    diff --git a/turbo.json b/turbo.json index fdca7f2..b3dc4a9 100644 --- a/turbo.json +++ b/turbo.json @@ -1,43 +1,68 @@ { "$schema": "https://turbo.build/schema.json", + "globalPassThroughEnv": [ + "PUBLIC_CHAINS", + "PUBLIC_POLLING_INTERVAL", + "PUBLIC_ALCHEMY_API_KEY", + "PUBLIC_WALLET_CONNECT_PROJECT_ID", + "PUBLIC_BURNER_WALLET_ONLY_LOCAL", + "PUBLIC_BURNER_WALLET_KEY" + ], "envMode": "strict", "ui": "stream", "tasks": { "format": { - "inputs": ["src/**", "test/**"], + "inputs": [ + "src/**", + "test/**" + ], "outputLogs": "new-only" }, "check": { - "dependsOn": ["format"], + "dependsOn": [ + "format" + ], "outputLogs": "new-only" }, "build": { - "dependsOn": ["check"], + "dependsOn": [ + "check" + ], "outputLogs": "new-only" }, "test": { - "dependsOn": ["build"], + "dependsOn": [ + "build" + ], "cache": false, "outputLogs": "new-only" }, "dev": { "cache": false, "persistent": true, - "inputs": ["src/**"], + "inputs": [ + "src/**" + ], "outputLogs": "new-only" }, "start": { - "dependsOn": ["check"], + "dependsOn": [ + "check" + ], "cache": false, "persistent": true, - "inputs": ["src/**"], + "inputs": [ + "src/**" + ], "outputLogs": "new-only" }, "preview": { - "dependsOn": ["build"], + "dependsOn": [ + "build" + ], "cache": false, "persistent": true, "outputLogs": "new-only" } } -} +} \ No newline at end of file