/ README.md
README.md
  1  <p align="center">
  2      <img src="docs/beaglegaze-transparent.png" alt="beaglegaze Logo" width="400"/>
  3  </p>
  4  
  5  # 💰 beaglegaze - Multi-Language Web3 Fee Collection Library
  6  
  7  > Transform your software into a monetized service with blockchain-powered micro-payments.
  8  
  9  [![Java Build](https://github.com/steffenboe/beaglegaze/actions/workflows/mvnBuild.yml/badge.svg)](https://github.com/steffenboe/beaglegaze/actions/workflows/mvnBuild.yml)
 10  [![Python Tests](https://github.com/steffenboe/beaglegaze/actions/workflows/python-test.yml/badge.svg)](https://github.com/steffenboe/beaglegaze/actions/workflows/python-test.yml)
 11  [![Node.js Build](https://github.com/steffenboe/beaglegaze/actions/workflows/nodejs-build.yml/badge.svg)](https://github.com/steffenboe/beaglegaze/actions/workflows/nodejs-build.yml)
 12  [![License: GPL v3](https://img.shields.io/badge/License-LGPLv3-blue.svg)](LICENSE)
 13  
 14  **beaglegaze** enables developers to seamlessly integrate fees collection into their libraries and services using blockchain technology. Users pre-fund a smart contract to access your code, and each function call triggers automatic micro-payments to registered contributors.
 15  
 16  ## 📋 Table of Contents
 17  
 18  - [Features](#-features)
 19  - [How It Works](#-how-it-works)
 20  - [Installation](#-installation)
 21  - [Examples](#-examples)
 22    - [Python Example](#python-example)
 23    - [Java Example](#java-example)
 24  - [Architecture](#-architecture)
 25  - [Contributing](#-contributing)
 26  - [License](#-license)
 27  
 28  ## ✨ Features
 29  
 30  - **🔗 Multi-language Support**: Available for Java and Python
 31  - **⚡ Asynchronous Processing**: Non-blocking fee collection with batch processing
 32  - **💳 Pre-funded Accounts**: Users fund smart contracts in advance
 33  - **🎯 Automatic Deduction**: Transparent fee collection on function calls
 34  - **🔒 Blockchain Security**: Ethereum-based smart contract infrastructure
 35  - **📊 Real-time Monitoring**: Track usage and payments in real-time
 36  
 37  ## 🔄 How It Works
 38  
 39  ![Payment Tracker Overview](docs/overview.png)
 40  
 41  1. **Pre-funding**: Clients deposit funds into the smart contract
 42  2. **Integration**: Developers integrate beaglegaze SDK into their libraries
 43  3. **Usage Tracking**: Function calls are automatically monitored
 44  4. **Fee Collection**: Micro-payments are deducted from client accounts
 45  5. **Distribution**: Payments are distributed to registered contributors
 46  
 47  > ⚠️ **Important**: Due to asynchronous processing, not every method invocation is immediately charged. Some calls may execute even with insufficient funding, but the library will eventually block when funds are depleted.
 48  
 49  ## 📦 Installation
 50  
 51  ### Prerequisites
 52  
 53  ```bash
 54  npm install --global solc
 55  ```
 56  
 57  ### Local Development Setup
 58  
 59  1. **Start Ethereum testnet**:
 60     ```bash
 61     docker buildx build -t hardhat-testnet deploy/hardhat-testnet/.
 62     docker run -d -p 8545:8545 --rm --name hardhat-testnet hardhat-testnet
 63     ```
 64  
 65  2. **Note the contract address** from the deployment logs:
 66     ```
 67     🎉 Deployment completed successfully!
 68     Contract address: 0x289B72CEeaB48832261626D62E3daA87Fd90B024
 69     ```
 70  
 71  ## 💡 Examples
 72  
 73  The following examples demonstrate the complete workflow:
 74  1. Deploy local Ethereum node with smart contract
 75  2. Integrate beaglegaze tracker into your code
 76  3. Attempt function calls without funding (fails)
 77  4. Fund the smart contract
 78  5. Successfully execute paid function calls
 79  
 80  ### Python Example
 81  
 82  **Setup Environment**:
 83  ```bash
 84  cd python-sdk
 85  python -m venv .venv
 86  source .venv/bin/activate
 87  pip install -e .
 88  cd demo
 89  python -i monetized_lib.py
 90  ```
 91  
 92  **Client Usage** (Interactive Python session):
 93  
 94  ```python
 95  import asyncio
 96  
 97  async def main():
 98      lib = MonetizedLibrary("0xcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")
 99      result = await lib.important_function()
100      print(result)
101  
102  asyncio.run(main())
103  ```
104  
105  **Expected Error** (Insufficient funding):
106  ```
107  raise ContractLogicError(f"execution reverted: {message}", data=data)
108  web3.exceptions.ContractLogicError: ("execution reverted: Error: VM Exception while processing transaction: reverted with reason string 'Insufficient client funding'", {'message': "Error: VM Exception while processing transaction: reverted with reason string 'Insufficient client funding'", 'data': '0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001b496e73756666696369656e7420636c69656e742066756e64696e670000000000'})
109  
110  [...]
111  
112  line 24, in handle
113  self._consume_from_contract(event)
114  File "/home/steffenboe/projects/coss-metering/python-sdk/python-sdk/contract_consumer.py", line 47, in _consume_from_contract
115  raise RuntimeError("Failed to consume from contract") from e
116  RuntimeError: Failed to consume from contract
117  ```
118  
119  **Fund the Contract**:
120  ```bash
121  python fund.py
122  ```
123  
124  **Successful Execution**:
125  ```python
126  asyncio.run(main())
127  ```
128  
129  **Expected Output**:
130  ```
131  Processing batch with sum 100...
132  Executing important_function with args=() and kwargs={}
133  Success
134  ```
135  
136  **Check Balance**:
137  ```python
138  balance = contract.functions.getClientFunding().call({'from': client_account.address})
139  print(f"client funding: {w3.from_wei(balance, 'ether')} ETH")
140  # Output: client funding: 0.0999999999995618 ETH
141  ```
142  
143  ### Java Example
144  
145  **Install Web3j**:
146  ```bash
147  curl -L get.web3j.io | sh && source ~/.web3j/source.sh
148  ```
149  
150  **Setup Project**:
151  ```bash
152  cd examples/java
153  cp ../../deploy/hardhat-testnet/contracts/UsageContract.sol src/main/resources/contracts
154  ```
155  
156  **Compile Smart Contract**:
157  ```bash
158  cd src/main/resources/contracts
159  solcjs UsageContract.sol --abi --bin -o .
160  cd ../../../../
161  web3j generate solidity -b src/main/resources/contracts/Beaglegaze_sol_Beaglegaze.bin -a src/main/resources/contracts/Beaglegaze_sol_Beaglegaze.abi -o src/main/java -p com.example
162  ```
163  
164  **Test Without Funding** (Expected to fail):
165  ```bash
166  mvn -Dtest=ClientTest test
167  ```
168  
169  **Expected Error**:
170  ```
171  18:54:18.308 [ForkJoinPool.commonPool-worker-1] ERROR web3.beaglegaze.ContractConsumer -- Failed to consume from contract, switching to 'blocked' state. Refund the smart contract to continue using this library.
172  java.lang.RuntimeException: Failed to consume from contract
173          at web3.beaglegaze.SmartContract.consume(SmartContract.java:48)
174          at web3.beaglegaze.ContractConsumer.consumeFromContract(ContractConsumer.java:57)
175          at web3.beaglegaze.ContractConsumer.handle(ContractConsumer.java:31)
176          at web3.beaglegaze.AsyncBatchProcessor.lambda$0(AsyncBatchProcessor.java:78)
177          at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
178          at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
179          at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
180          at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
181          at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
182          at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
183          at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
184  Caused by: org.web3j.protocol.exceptions.TransactionException: {"message":"Error: VM Exception while processing transaction: reverted with reason string 'Insufficient client funding'","txHash":"0xc7f529bd3a7662be5d095b815823277ca99ba3454fde819e5add8d65a1ef491c","data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001b496e73756666696369656e7420636c69656e742066756e64696e670000000000"}
185  ```
186  
187  **Fund the Contract**:
188  ```bash
189  mvn -Dtest=FundTest test
190  ```
191  
192  **Test With Funding** (Should succeed):
193  ```bash
194  mvn -Dtest=ClientTest test
195  ```
196  
197  **Expected Success Output**:
198  ```
199  19:04:32.377 [main] INFO web3.beaglegaze.AsyncBatchProcessor -- Processing batch with sum 100...
200  [Call tracked]: com.example.Main.main
201  Successfully called main method!
202  Called main 10 times
203  ```
204  
205  ## Radicle
206  To clone this repo using Radicle, run 
207  
208  ˋˋ`bash
209  rad clone rad:z4KTnYMX3CfwpB4PVFVoUNGvNnxDJ
210  ˋˋ`
211  
212  
213  ## 📄 License
214  
215  This project is licensed under the LGPL v3 License - see the [LICENSE](LICENSE) file for details.
216  
217  ---
218  
219  <div align="center">
220    <p>Built with ❤️ for the Web3 community</p>
221    <p>
222      <a href="#top">Back to Top</a> •
223      <a href="https://github.com/beaglegaze/beaglegaze-java-sdk/issues">Report Bug</a> •
224      <a href="https://github.com/beaglegaze/beaglegaze-java-sdk/issues">Request Feature</a>
225    </p>
226  </div>